hayai_junit_xml_outputter.hpp
Go to the documentation of this file.
00001 #ifndef __HAYAI_JUNITXMLOUTPUTTER
00002 #define __HAYAI_JUNITXMLOUTPUTTER
00003 #include <iomanip>
00004 #include <ostream>
00005 #include <vector>
00006 #include <sstream>
00007 #include <map>
00008 
00009 #include "hayai/hayai_outputter.hpp"
00010 
00011 
00012 namespace hayai
00013 {
00015     class JUnitXmlOutputter
00016         :   public Outputter
00017     {
00018     private:
00020         class TestCase
00021         {
00022         public:
00023             TestCase(const std::string& fixtureName,
00024                      const std::string& testName,
00025                      const TestParametersDescriptor& parameters,
00026                      const TestResult* result)
00027             {
00028                 // Derive a pretty name.
00029                 std::stringstream nameStream;
00030                 WriteTestNameToStream(nameStream,
00031                                       fixtureName,
00032                                       testName,
00033                                       parameters);
00034                 Name = nameStream.str();
00035 
00036                 // Derive the result.
00037                 Skipped = !result;
00038 
00039                 if (result)
00040                 {
00041                     std::stringstream timeStream;
00042                     timeStream << std::fixed
00043                                << std::setprecision(9)
00044                                << (result->IterationTimeAverage() / 1e9);
00045                     Time = timeStream.str();
00046                 }
00047             }
00048 
00049 
00050             std::string Name;
00051             std::string Time;
00052             bool Skipped;
00053         };
00054 
00055 
00057         typedef std::map<std::string, std::vector<TestCase> > TestSuiteMap;
00058     public:
00060 
00063         JUnitXmlOutputter(std::ostream& stream)
00064             :   _stream(stream)
00065         {
00066 
00067         }
00068 
00069 
00070         virtual void Begin(const std::size_t& enabledCount,
00071                            const std::size_t& disabledCount)
00072         {
00073             (void)enabledCount;
00074             (void)disabledCount;
00075         }
00076 
00077 
00078         virtual void End(const std::size_t& executedCount,
00079                          const std::size_t& disabledCount)
00080         {
00081             (void)executedCount;
00082             (void)disabledCount;
00083 
00084             // Write the header.
00085             _stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
00086                     << std::endl
00087                     << "<testsuites>" << std::endl;
00088 
00089             // Write out each test suite (fixture.)
00090             for (TestSuiteMap::iterator testSuiteIt = _testSuites.begin();
00091                     testSuiteIt != _testSuites.end();
00092                     ++testSuiteIt)
00093             {
00094                 _stream << "    <testsuite name=\"" << testSuiteIt->first
00095                         << "\" tests=\"" << testSuiteIt->second.size() << "\">"
00096                         << std::endl;
00097 
00098                 // Write out each test case.
00099                 for (std::vector<TestCase>::iterator testCaseIt =
00100                             testSuiteIt->second.begin();
00101                         testCaseIt != testSuiteIt->second.end();
00102                         ++testCaseIt)
00103                 {
00104                     _stream << "        <testcase name=\"";
00105                     WriteEscapedString(testCaseIt->Name);
00106                     _stream << "\"";
00107 
00108                     if (!testCaseIt->Skipped)
00109                         _stream << " time=\"" << testCaseIt->Time << "\" />"
00110                                 << std::endl;
00111                     else
00112                     {
00113                         _stream << ">" << std::endl
00114                                 << "            <skipped />" << std::endl
00115                                 << "        </testcase>" << std::endl;
00116                     }
00117                 }
00118 
00119                 _stream << "    </testsuite>" << std::endl;
00120             }
00121 
00122             _stream << "</testsuites>" << std::endl;
00123         }
00124 
00125 
00126         virtual void BeginTest(const std::string& fixtureName,
00127                                const std::string& testName,
00128                                const TestParametersDescriptor& parameters,
00129                                const std::size_t& runsCount,
00130                                const std::size_t& iterationsCount)
00131         {
00132             (void)fixtureName;
00133             (void)testName;
00134             (void)parameters;
00135             (void)runsCount;
00136             (void)iterationsCount;
00137         }
00138 
00139 
00140         virtual void SkipDisabledTest(const std::string& fixtureName,
00141                                       const std::string& testName,
00142                                       const TestParametersDescriptor& parameters,
00143                                       const std::size_t& runsCount,
00144                                       const std::size_t& iterationsCount)
00145         {
00146             (void)fixtureName;
00147             (void)testName;
00148             (void)parameters;
00149             (void)runsCount;
00150             (void)iterationsCount;
00151         }
00152 
00153 
00154         virtual void EndTest(const std::string& fixtureName,
00155                              const std::string& testName,
00156                              const TestParametersDescriptor& parameters,
00157                              const TestResult& result)
00158         {
00159             (void)fixtureName;
00160             (void)testName;
00161             (void)parameters;
00162 
00163             TestSuiteMap::iterator fixtureIt =
00164                 _testSuites.find(fixtureName);
00165 
00166             if (fixtureIt == _testSuites.end())
00167             {
00168                 _testSuites[fixtureName] = std::vector<TestCase>();
00169                 fixtureIt = _testSuites.find(fixtureName);
00170             }
00171 
00172             std::vector<TestCase>& testCases = fixtureIt->second;
00173 
00174             testCases.push_back(TestCase(fixtureName,
00175                                          testName,
00176                                          parameters,
00177                                          &result));
00178 
00179             /*
00180             _stream <<
00181                 JSON_VALUE_SEPARATOR
00182 
00183                 JSON_STRING_BEGIN "runs" JSON_STRING_END
00184                 JSON_NAME_SEPARATOR
00185                 JSON_ARRAY_BEGIN;
00186 
00187             const std::vector<uint64_t>& runTimes = result.RunTimes();
00188 
00189             for (std::vector<uint64_t>::const_iterator it = runTimes.begin();
00190                  it != runTimes.end();
00191                  ++it)
00192             {
00193                 if (it != runTimes.begin())
00194                     _stream << JSON_VALUE_SEPARATOR;
00195 
00196                 _stream << JSON_OBJECT_BEGIN
00197 
00198                            JSON_STRING_BEGIN "duration" JSON_STRING_END
00199                            JSON_NAME_SEPARATOR
00200                         << std::fixed
00201                         << std::setprecision(6)
00202                         << (double(*it) / 1000000.0)
00203                         << JSON_OBJECT_END;
00204             }
00205 
00206             _stream <<
00207                 JSON_ARRAY_END;
00208 
00209             EndTestObject();
00210             */
00211         }
00212     private:
00214 
00219         void WriteEscapedString(const std::string& str)
00220         {
00221             std::string::const_iterator it = str.begin();
00222 
00223             while (it != str.end())
00224             {
00225                 char c = *it++;
00226 
00227                 switch (c)
00228                 {
00229                     case '"':
00230                         _stream << "&quot;";
00231                         break;
00232 
00233                     case '\'':
00234                         _stream << "&apos;";
00235                         break;
00236 
00237                     case '<':
00238                         _stream << "&lt;";
00239                         break;
00240 
00241                     case '>':
00242                         _stream << "&gt;";
00243                         break;
00244 
00245                     case '&':
00246                         _stream << "&amp;";
00247                         break;
00248 
00249                     default:
00250                         _stream << c;
00251                         break;
00252                 }
00253             }
00254         }
00255 
00256 
00257         std::ostream& _stream;
00258         TestSuiteMap _testSuites;
00259     };
00260 }
00261 
00262 #endif


hayai
Author(s): Nick Bruun
autogenerated on Thu Jun 6 2019 18:13:43