Commits

Matt Oswald committed 9dd2a7d

fixing some xml output, adding xml output tests

  • Participants
  • Parent commits e474cfa

Comments (0)

Files changed (14)

Tests/Helpers/OutputRecord.cpp

+#include "OutputRecord.h"
+#include "xUnit++/LineInfo.h"
+#include "xUnit++/TestDetails.h"
+#include "xUnit++/TestEvent.h"
+
+namespace xUnitpp { namespace Tests {
+
+void OutputRecord::ReportStart(const ITestDetails &testDetails)
+{
+    std::lock_guard<std::mutex> guard(lock);
+    orderedTestList.push_back(static_cast<const TestDetails &>(testDetails));
+}
+
+void OutputRecord::ReportEvent(const ITestDetails &testDetails, const ITestEvent &evt)
+{
+    std::lock_guard<std::mutex> guard(lock);
+    events.push_back(std::make_pair(static_cast<const TestDetails &>(testDetails), static_cast<const TestEvent &>(evt)));
+}
+
+void OutputRecord::ReportSkip(const ITestDetails &testDetails, const char *reason)
+{
+    std::lock_guard<std::mutex> guard(lock);
+    skips.push_back(std::make_pair(static_cast<const TestDetails &>(testDetails), reason));
+}
+
+void OutputRecord::ReportFinish(const ITestDetails &testDetails, long long nsTaken)
+{
+    std::lock_guard<std::mutex> guard(lock);
+    finishedTests.push_back(std::make_pair(static_cast<const TestDetails &>(testDetails), Time::Duration(nsTaken)));
+}
+
+void OutputRecord::ReportAllTestsComplete(size_t testCount, size_t skipped, size_t failed, long long nsTotal)
+{
+    summaryCount = testCount;
+    summarySkipped = skipped;
+    summaryFailed = failed;
+    summaryDuration = Time::Duration(nsTotal);
+}
+
+}}

Tests/Helpers/OutputRecord.h

+#ifndef OUTPUTRECORD_H_
+#define OUTPUTRECORD_H_
+
+#include <memory>
+#include <mutex>
+#include <tuple>
+#include <utility>
+#include <vector>
+#include "xUnit++/IOutput.h"
+
+namespace xUnitpp
+{
+    struct TestDetails;
+    class TestEvent;
+}
+
+namespace xUnitpp { namespace Tests {
+
+class OutputRecord : public IOutput
+{
+public:
+    virtual void __stdcall ReportStart(const ITestDetails &testDetails) override;
+    virtual void __stdcall ReportEvent(const ITestDetails &testDetails, const ITestEvent &evt) override;
+    virtual void __stdcall ReportSkip(const ITestDetails &testDetails, const char *reason) override;
+    virtual void __stdcall ReportFinish(const ITestDetails &testDetails, long long nsTaken) override;
+    virtual void __stdcall ReportAllTestsComplete(size_t testCount, size_t skipped, size_t failed, long long nsTotal) override;
+
+    std::vector<TestDetails> orderedTestList;
+    std::vector<std::pair<TestDetails, TestEvent>> events;
+    std::vector<std::pair<TestDetails, std::string>> skips;
+    std::vector<std::pair<TestDetails, Time::Duration>> finishedTests;
+
+    size_t summaryCount;
+    size_t summarySkipped;
+    size_t summaryFailed;
+    Time::Duration summaryDuration;
+
+private:
+    std::mutex lock;
+};
+
+}}
+
+#endif

Tests/Helpers/TestFactory.cpp

+#include "TestFactory.h"
+#include "xUnit++/TestEventRecorder.h"
+#include "xUnit++/xUnitTest.h"
+
+namespace xUnitpp { namespace Tests {
+
+TestFactory::TestFactory(std::function<void()> testFn)
+    : testFn(testFn)
+    , testEventRecorders()
+    , timeLimit(-1)
+    , file("dummy.cpp")
+    , line(0)
+{
+}
+
+TestFactory::TestFactory(std::function<void()> testFn, std::vector<std::shared_ptr<xUnitpp::TestEventRecorder>> testEventRecorders)
+    : testFn(testFn)
+    , testEventRecorders(testEventRecorders)
+    , timeLimit(-1)
+    , file("dummy.cpp")
+    , line(0)
+{
+}
+
+TestFactory &TestFactory::Name(const std::string &name)
+{
+    this->name = name;
+    return *this;
+}
+
+TestFactory &TestFactory::Suite(const std::string &suite)
+{
+    this->suite = suite;
+    return *this;
+}
+
+TestFactory &TestFactory::Duration(Time::Duration timeLimit)
+{
+    this->timeLimit = timeLimit;
+    return *this;
+}
+
+TestFactory &TestFactory::Attributes(const xUnitpp::AttributeCollection &attributes)
+{
+    this->attributes = attributes;
+    return *this;
+}
+
+TestFactory &TestFactory::TestFile(const std::string &file)
+{
+    this->file = file;
+    return *this;
+}
+
+TestFactory &TestFactory::TestLine(int line)
+{
+    this->line = line;
+    return *this;
+}
+
+TestFactory::operator std::shared_ptr<xUnitTest>()
+{
+    return std::make_shared<xUnitTest>(std::move(testFn), std::string(name), 0, "", suite, std::move(attributes), timeLimit, std::move(file), line, testEventRecorders);
+}
+
+}}

Tests/Helpers/TestFactory.h

+#ifndef TESTFACTORY_H_
+#define TESTFACTORY_H_
+
+#include <functional>
+#include <memory>
+#include <string>
+#include <vector>
+#include "xUnit++/Attributes.h"
+#include "xUnit++/xUnitTime.h"
+
+namespace xUnitpp
+{
+    class TestEventRecorder;
+    class xUnitTest;
+}
+
+namespace xUnitpp { namespace Tests {
+
+struct TestFactory
+{
+    TestFactory(std::function<void()> testFn);
+    TestFactory(std::function<void()> testFn, std::vector<std::shared_ptr<xUnitpp::TestEventRecorder>> testEventRecorders);
+
+    TestFactory &Name(const std::string &name);
+    TestFactory &Suite(const std::string &suite);
+    TestFactory &Duration(Time::Duration timeLimit);
+    TestFactory &Attributes(const xUnitpp::AttributeCollection &attributes);
+    TestFactory &TestFile(const std::string &file);
+    TestFactory &TestLine(int line);
+    operator std::shared_ptr<xUnitTest>();
+
+private:
+    std::function<void()> testFn;
+    std::vector<std::shared_ptr<xUnitpp::TestEventRecorder>> testEventRecorders;
+    std::string name;
+    std::string suite;
+    Time::Duration timeLimit;
+    xUnitpp::AttributeCollection attributes;
+    std::string file;
+    int line;
+};
+
+}}
+
+#endif

Tests/UnitTests/Helpers/OutputRecord.cpp

-#include "OutputRecord.h"
-#include "xUnit++/LineInfo.h"
-#include "xUnit++/TestDetails.h"
-#include "xUnit++/TestEvent.h"
-
-namespace xUnitpp { namespace Tests {
-
-void OutputRecord::ReportStart(const ITestDetails &testDetails)
-{
-    std::lock_guard<std::mutex> guard(lock);
-    orderedTestList.push_back(static_cast<const TestDetails &>(testDetails));
-}
-
-void OutputRecord::ReportEvent(const ITestDetails &testDetails, const ITestEvent &evt)
-{
-    std::lock_guard<std::mutex> guard(lock);
-    events.push_back(std::make_pair(static_cast<const TestDetails &>(testDetails), static_cast<const TestEvent &>(evt)));
-}
-
-void OutputRecord::ReportSkip(const ITestDetails &testDetails, const char *reason)
-{
-    std::lock_guard<std::mutex> guard(lock);
-    skips.push_back(std::make_pair(static_cast<const TestDetails &>(testDetails), reason));
-}
-
-void OutputRecord::ReportFinish(const ITestDetails &testDetails, long long nsTaken)
-{
-    std::lock_guard<std::mutex> guard(lock);
-    finishedTests.push_back(std::make_pair(static_cast<const TestDetails &>(testDetails), Time::Duration(nsTaken)));
-}
-
-void OutputRecord::ReportAllTestsComplete(size_t testCount, size_t skipped, size_t failed, long long nsTotal)
-{
-    summaryCount = testCount;
-    summarySkipped = skipped;
-    summaryFailed = failed;
-    summaryDuration = Time::Duration(nsTotal);
-}
-
-}}

Tests/UnitTests/Helpers/OutputRecord.h

-#ifndef OUTPUTRECORD_H_
-#define OUTPUTRECORD_H_
-
-#include <memory>
-#include <mutex>
-#include <tuple>
-#include <utility>
-#include <vector>
-#include "xUnit++/IOutput.h"
-
-namespace xUnitpp
-{
-    struct TestDetails;
-    class TestEvent;
-}
-
-namespace xUnitpp { namespace Tests {
-
-class OutputRecord : public IOutput
-{
-public:
-    virtual void __stdcall ReportStart(const ITestDetails &testDetails) override;
-    virtual void __stdcall ReportEvent(const ITestDetails &testDetails, const ITestEvent &evt) override;
-    virtual void __stdcall ReportSkip(const ITestDetails &testDetails, const char *reason) override;
-    virtual void __stdcall ReportFinish(const ITestDetails &testDetails, long long nsTaken) override;
-    virtual void __stdcall ReportAllTestsComplete(size_t testCount, size_t skipped, size_t failed, long long nsTotal) override;
-
-    std::vector<TestDetails> orderedTestList;
-    std::vector<std::pair<TestDetails, TestEvent>> events;
-    std::vector<std::pair<TestDetails, std::string>> skips;
-    std::vector<std::pair<TestDetails, Time::Duration>> finishedTests;
-
-    size_t summaryCount;
-    size_t summarySkipped;
-    size_t summaryFailed;
-    Time::Duration summaryDuration;
-
-private:
-    std::mutex lock;
-};
-
-}}
-
-#endif

Tests/UnitTests/TestRunner.cpp

 #include "xUnit++/xUnitTestRunner.h"
 #include "xUnit++/xUnitTime.h"
 #include "Helpers/OutputRecord.h"
+#include "Helpers/TestFactory.h"
 
 using xUnitpp::Assert;
 using xUnitpp::xUnitTest;
 using xUnitpp::RunTests;
 namespace Tests = xUnitpp::Tests;
 namespace Time = xUnitpp::Time;
+using Tests::TestFactory;
 
 SUITE("TestRunner")
 {
 
-struct TestFactory
-{
-    TestFactory(std::function<void()> testFn, std::vector<std::shared_ptr<xUnitpp::TestEventRecorder>> testEventRecorders)
-        : testFn(testFn)
-        , testEventRecorders(testEventRecorders)
-        , timeLimit(-1)
-        , file("dummy.cpp")
-        , line(0)
-    {
-    }
-
-    TestFactory &Name(const std::string &name)
-    {
-        this->name = name;
-        return *this;
-    }
-
-    TestFactory &Suite(const std::string &suite)
-    {
-        this->suite = suite;
-        return *this;
-    }
-
-    TestFactory &Duration(Time::Duration timeLimit)
-    {
-        this->timeLimit = timeLimit;
-        return *this;
-    }
-
-    TestFactory &Attributes(const xUnitpp::AttributeCollection &attributes)
-    {
-        this->attributes = attributes;
-        return *this;
-    }
-
-    TestFactory &TestFile(const std::string &file)
-    {
-        this->file = file;
-        return *this;
-    }
-
-    TestFactory &TestLine(int line)
-    {
-        this->line = line;
-        return *this;
-    }
-
-    operator std::shared_ptr<xUnitTest>()
-    {
-        return std::make_shared<xUnitTest>(std::move(testFn), std::string(name), 0, "", suite, std::move(attributes), timeLimit, std::move(file), line, testEventRecorders);
-    }
-
-private:
-    std::function<void()> testFn;
-    std::vector<std::shared_ptr<xUnitpp::TestEventRecorder>> testEventRecorders;
-    std::string name;
-    std::string suite;
-    Time::Duration timeLimit;
-    xUnitpp::AttributeCollection attributes;
-    std::string file;
-    int line;
-};
-
 struct TestRunnerFixture
 {
     TestRunnerFixture()

Tests/UnitTests/UnitTests.vcxproj

   <PropertyGroup Label="UserMacros" />
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
-      <AdditionalIncludeDirectories>$(SolutionDir)xUnit++</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(SolutionDir)xUnit++;../</AdditionalIncludeDirectories>
     </ClCompile>
     <PostBuildEvent>
       <Command>"$(OutputPath)../xUnit++.console/xUnit++.console.$(PlatformShortName)$(DebugTag).exe" "$(TargetPath)" -g</Command>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <ClCompile>
-      <AdditionalIncludeDirectories>$(SolutionDir)xUnit++</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(SolutionDir)xUnit++;../</AdditionalIncludeDirectories>
     </ClCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
-      <AdditionalIncludeDirectories>$(SolutionDir)xUnit++</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(SolutionDir)xUnit++;../</AdditionalIncludeDirectories>
     </ClCompile>
     <PostBuildEvent>
       <Command>"$(OutputPath)../xUnit++.console/xUnit++.console.$(PlatformShortName)$(DebugTag).exe" "$(TargetPath)" -g</Command>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <ClCompile>
-      <AdditionalIncludeDirectories>$(SolutionDir)xUnit++</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(SolutionDir)xUnit++;../</AdditionalIncludeDirectories>
     </ClCompile>
     <PostBuildEvent>
       <Command>"$(OutputPath)../xUnit++.console/xUnit++.console.$(PlatformShortName)$(DebugTag).exe" "$(TargetPath)"</Command>
     </PostBuildEvent>
   </ItemDefinitionGroup>
   <ItemGroup>
+    <ClCompile Include="..\Helpers\OutputRecord.cpp" />
+    <ClCompile Include="..\Helpers\TestFactory.cpp" />
     <ClCompile Include="Assert.Contains.cpp" />
     <ClCompile Include="Assert.DoesNotContain.cpp" />
     <ClCompile Include="Assert.DoesNotThrow.cpp" />
     <ClCompile Include="Assert.True.cpp" />
     <ClCompile Include="Attributes.cpp" />
     <ClCompile Include="ErrorHandling.cpp" />
-    <ClCompile Include="Helpers\OutputRecord.cpp" />
     <ClCompile Include="LineInfo.cpp" />
     <ClCompile Include="TestEvents.cpp" />
     <ClCompile Include="TestRunner.cpp" />
     </ProjectReference>
   </ItemGroup>
   <ItemGroup>
-    <ClInclude Include="Helpers\OutputRecord.h" />
+    <ClInclude Include="..\Helpers\OutputRecord.h" />
+    <ClInclude Include="..\Helpers\TestFactory.h" />
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">

Tests/UnitTests/UnitTests.vcxproj.filters

     <ClCompile Include="Theory.cpp" />
     <ClCompile Include="LineInfo.cpp" />
     <ClCompile Include="TestRunner.cpp" />
-    <ClCompile Include="Helpers\OutputRecord.cpp">
-      <Filter>Test Helpers</Filter>
-    </ClCompile>
     <ClCompile Include="TestsCanOutputAnythingWithToString.cpp" />
     <ClCompile Include="TestEvents.cpp" />
     <ClCompile Include="ToString.cpp" />
     <ClCompile Include="ErrorHandling.cpp" />
+    <ClCompile Include="..\Helpers\OutputRecord.cpp">
+      <Filter>Test Helpers</Filter>
+    </ClCompile>
+    <ClCompile Include="..\Helpers\TestFactory.cpp">
+      <Filter>Test Helpers</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <Filter Include="Test Helpers">
     </Filter>
   </ItemGroup>
   <ItemGroup>
-    <ClInclude Include="Helpers\OutputRecord.h">
+    <ClInclude Include="..\Helpers\OutputRecord.h">
+      <Filter>Test Helpers</Filter>
+    </ClInclude>
+    <ClInclude Include="..\Helpers\TestFactory.h">
       <Filter>Test Helpers</Filter>
     </ClInclude>
   </ItemGroup>

Tests/UtilityTests/TestXmlReporter.cpp

 #include "xUnit++/xUnit++.h"
+#include "xUnit++/xUnitTestRunner.h"
 #include "XmlReporter.h"
 #include "tinyxml2.h"
+#include "Helpers/TestFactory.h"
 
 using xUnitpp::Utilities::XmlReporter;
+using xUnitpp::Tests::TestFactory;
+
+namespace
+{
+    namespace Filter
+    {
+        bool AllTests(const xUnitpp::ITestDetails &) { return true; }
+        bool NoTests(const xUnitpp::ITestDetails &) { return false; }
+    }
+
+    class LocalTester
+    {
+    public:
+        void Register(std::shared_ptr<xUnitpp::xUnitTest> test)
+        {
+            tests.push_back(test);
+        }
+
+        void Run(xUnitpp::IOutput &reporter)
+        {
+            xUnitpp::RunTests(reporter, &Filter::AllTests, tests, xUnitpp::Time::Duration::zero(), 0);
+        }
+
+    private:
+        std::vector<std::shared_ptr<xUnitpp::xUnitTest>> tests;
+    };
+}
 
 SUITE("XmlReporter")
 {
     Assert.Equal(tinyxml2::XMLError::XML_SUCCESS, tinyxml2::XMLDocument().Parse(out.str().c_str()));
 }
 
+DATA_THEORY("XmlReporter generates valid xml after running tests", (std::function<void ()> test),
+    ([]() -> std::vector<std::tuple<std::function<void()>>>
+    {
+        std::vector<std::tuple<std::function<void()>>> tests;
+
+        tests.emplace_back([]() { Assert.True(true); });
+        tests.emplace_back([]() { Assert.True(false); });
+        tests.emplace_back(
+            []()
+            {
+                Assert.True(true);
+                Assert.True(false);
+            });
+
+        return tests;
+    })
+)
+{
+    std::stringstream out;
+
+    XmlReporter reporter(out);
+
+    {
+        LocalTester local;
+        local.Register(TestFactory(test).Name("Success"));
+
+        local.Run(reporter);
+    }
+
+    Assert.Equal(tinyxml2::XMLError::XML_SUCCESS, tinyxml2::XMLDocument().Parse(out.str().c_str()));
 }
+
+}

Tests/UtilityTests/UtilityTests.vcxproj

   <PropertyGroup Label="UserMacros" />
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
-      <AdditionalIncludeDirectories>$(SolutionDir)xUnit++;$(SolutionDir)xUnit++.Utility;$(SolutionDir)external/tinyxml2</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(SolutionDir)xUnit++;$(SolutionDir)xUnit++.Utility;$(SolutionDir)external/tinyxml2;../</AdditionalIncludeDirectories>
     </ClCompile>
     <PostBuildEvent>
       <Command>"$(OutputPath)../xUnit++.console/xUnit++.console.$(PlatformShortName)$(DebugTag).exe" "$(TargetPath)"</Command>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <ClCompile>
-      <AdditionalIncludeDirectories>$(SolutionDir)xUnit++;$(SolutionDir)xUnit++.Utility;$(SolutionDir)external/tinyxml2</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(SolutionDir)xUnit++;$(SolutionDir)xUnit++.Utility;$(SolutionDir)external/tinyxml2;../</AdditionalIncludeDirectories>
     </ClCompile>
     <PostBuildEvent>
       <Command>"$(OutputPath)../xUnit++.console/xUnit++.console.$(PlatformShortName)$(DebugTag).exe" "$(TargetPath)"</Command>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
-      <AdditionalIncludeDirectories>$(SolutionDir)xUnit++;$(SolutionDir)xUnit++.Utility;$(SolutionDir)external/tinyxml2</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(SolutionDir)xUnit++;$(SolutionDir)xUnit++.Utility;$(SolutionDir)external/tinyxml2;../</AdditionalIncludeDirectories>
     </ClCompile>
     <PostBuildEvent>
       <Command>"$(OutputPath)../xUnit++.console/xUnit++.console.$(PlatformShortName)$(DebugTag).exe" "$(TargetPath)"</Command>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <ClCompile>
-      <AdditionalIncludeDirectories>$(SolutionDir)xUnit++;$(SolutionDir)xUnit++.Utility;$(SolutionDir)external/tinyxml2</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(SolutionDir)xUnit++;$(SolutionDir)xUnit++.Utility;$(SolutionDir)external/tinyxml2;../</AdditionalIncludeDirectories>
     </ClCompile>
     <PostBuildEvent>
       <Command>"$(OutputPath)../xUnit++.console/xUnit++.console.$(PlatformShortName)$(DebugTag).exe" "$(TargetPath)"</Command>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\external\tinyxml2\tinyxml2.cpp" />
+    <ClCompile Include="..\Helpers\OutputRecord.cpp" />
+    <ClCompile Include="..\Helpers\TestFactory.cpp" />
     <ClCompile Include="TestXmlReporter.cpp" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\external\tinyxml2\tinyxml2.h" />
+    <ClInclude Include="..\Helpers\OutputRecord.h" />
+    <ClInclude Include="..\Helpers\TestFactory.h" />
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">

Tests/UtilityTests/UtilityTests.vcxproj.filters

     <ClCompile Include="..\..\external\tinyxml2\tinyxml2.cpp">
       <Filter>tinyxml2</Filter>
     </ClCompile>
+    <ClCompile Include="..\Helpers\OutputRecord.cpp">
+      <Filter>Test Helpers</Filter>
+    </ClCompile>
+    <ClCompile Include="..\Helpers\TestFactory.cpp">
+      <Filter>Test Helpers</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <Filter Include="tinyxml2">
       <UniqueIdentifier>{b5b936d5-a571-420f-b567-afbdd474d2c4}</UniqueIdentifier>
     </Filter>
+    <Filter Include="Test Helpers">
+      <UniqueIdentifier>{d337c62d-1644-4d9c-bce5-590605af4060}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\external\tinyxml2\tinyxml2.h">
       <Filter>tinyxml2</Filter>
     </ClInclude>
+    <ClInclude Include="..\Helpers\OutputRecord.h">
+      <Filter>Test Helpers</Filter>
+    </ClInclude>
+    <ClInclude Include="..\Helpers\TestFactory.h">
+      <Filter>Test Helpers</Filter>
+    </ClInclude>
   </ItemGroup>
 </Project>

xUnit++.Utility/XmlReporter.cpp

             result += std::string("         ") +
                 "<failure" +
                     XmlAttribute("message", fileAndLine + ": " + XmlEscape(message)) +
-                "</failure>\n";
+                " />\n";
         }
 
         return result;
         {
             output << XmlBeginTest(test.testDetails.GetFullName(), test);
 
-            if (test.status != TestResult::Success || test.testDetails.GetAttributeCount() == 0)
+            if (test.status != TestResult::Success || test.testDetails.GetAttributeCount() != 0)
             {
                 // close <TestCase>
                 output << ">\n";

xUnit++/xUnit++/xUnitToString.h

     using ToStringImpl::fallback::to_string;
     using std::to_string;
 
-    return ToStringImpl::to_string_impl<(sizeof (ToStringImpl::fallback::flag(), to_string(t), ToStringImpl::fallback::flag()) != sizeof(char))>::to_string(t);
+    return ToStringImpl::to_string_impl<(sizeof (ToStringImpl::fallback::flag(), to_string(std::declval<T>()), ToStringImpl::fallback::flag()) != sizeof(char))>::to_string(t);
 }
 
 template<typename T>
     using ToStringImpl::fallback::to_string;
     using std::to_string;
 
-    return (sizeof (ToStringImpl::fallback::flag(), to_string((T &)*(T *)nullptr), ToStringImpl::fallback::flag()) != sizeof(char));
+    return (sizeof (ToStringImpl::fallback::flag(), to_string(std::declval<T>()), ToStringImpl::fallback::flag()) != sizeof(char));
 }
 
 }