Provide JunitReporter declaration with EXTERNAL_INTERFACES

Related to #991
This commit is contained in:
Martin Hořeňovský 2017-11-14 17:12:51 +01:00
parent 6acdacfde0
commit 4b3730de8a
4 changed files with 233 additions and 179 deletions

View File

@ -248,6 +248,7 @@ set(REPORTER_HEADERS
${HEADER_DIR}/reporters/catch_reporter_automake.hpp
${HEADER_DIR}/reporters/catch_reporter_bases.hpp
${HEADER_DIR}/reporters/catch_reporter_compact.h
${HEADER_DIR}/reporters/catch_reporter_junit.h
${HEADER_DIR}/reporters/catch_reporter_multi.h
${HEADER_DIR}/reporters/catch_reporter_tap.hpp
${HEADER_DIR}/reporters/catch_reporter_teamcity.hpp

View File

@ -13,5 +13,6 @@
// Allow users to base their work off existing reporters
#include "../reporters/catch_reporter_compact.h"
#include "../reporters/catch_reporter_junit.h"
#endif // TWOBLUECUBES_CATCH_EXTERNAL_INTERFACES_H_INCLUDED

View File

@ -8,10 +8,10 @@
#include "catch_reporter_bases.hpp"
#include "catch_reporter_junit.h"
#include "../internal/catch_tostring.h"
#include "../internal/catch_reporter_registrars.hpp"
#include "internal/catch_xmlwriter.h"
#include "../internal/catch_timer.h"
#include <assert.h>
#include <sstream>
@ -55,64 +55,63 @@ namespace Catch {
return it->substr(1);
return std::string();
}
}
} // anonymous namespace
class JunitReporter : public CumulativeReporterBase<JunitReporter> {
public:
JunitReporter( ReporterConfig const& _config )
JunitReporter::JunitReporter( ReporterConfig const& _config )
: CumulativeReporterBase( _config ),
xml( _config.stream() )
{
m_reporterPrefs.shouldRedirectStdOut = true;
}
~JunitReporter() override;
JunitReporter::~JunitReporter() {};
static std::string getDescription() {
std::string JunitReporter::getDescription() {
return "Reports test results in an XML format that looks like Ant's junitreport target";
}
void noMatchingTestCases( std::string const& /*spec*/ ) override {}
void JunitReporter::noMatchingTestCases( std::string const& /*spec*/ ) {}
void testRunStarting( TestRunInfo const& runInfo ) override {
void JunitReporter::testRunStarting( TestRunInfo const& runInfo ) {
CumulativeReporterBase::testRunStarting( runInfo );
xml.startElement( "testsuites" );
}
void testGroupStarting( GroupInfo const& groupInfo ) override {
void JunitReporter::testGroupStarting( GroupInfo const& groupInfo ) {
suiteTimer.start();
stdOutForSuite.str("");
stdErrForSuite.str("");
stdOutForSuite.clear();
stdErrForSuite.clear();
unexpectedExceptions = 0;
CumulativeReporterBase::testGroupStarting( groupInfo );
}
void testCaseStarting( TestCaseInfo const& testCaseInfo ) override {
void JunitReporter::testCaseStarting( TestCaseInfo const& testCaseInfo ) {
m_okToFail = testCaseInfo.okToFail();
}
bool assertionEnded( AssertionStats const& assertionStats ) override {
bool JunitReporter::assertionEnded( AssertionStats const& assertionStats ) {
if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException && !m_okToFail )
unexpectedExceptions++;
return CumulativeReporterBase::assertionEnded( assertionStats );
}
void testCaseEnded( TestCaseStats const& testCaseStats ) override {
stdOutForSuite << testCaseStats.stdOut;
stdErrForSuite << testCaseStats.stdErr;
void JunitReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
stdOutForSuite += testCaseStats.stdOut;
stdErrForSuite += testCaseStats.stdErr;
CumulativeReporterBase::testCaseEnded( testCaseStats );
}
void testGroupEnded( TestGroupStats const& testGroupStats ) override {
void JunitReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
double suiteTime = suiteTimer.getElapsedSeconds();
CumulativeReporterBase::testGroupEnded( testGroupStats );
writeGroup( *m_testGroups.back(), suiteTime );
}
void testRunEndedCumulative() override {
void JunitReporter::testRunEndedCumulative() {
xml.endElement();
}
void writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
void JunitReporter::writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
TestGroupStats const& stats = groupNode.value;
xml.writeAttribute( "name", stats.groupInfo.name );
@ -130,11 +129,11 @@ namespace Catch {
for( auto const& child : groupNode.children )
writeTestCase( *child );
xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite.str() ), false );
xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite.str() ), false );
xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite ), false );
xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite ), false );
}
void writeTestCase( TestCaseNode const& testCaseNode ) {
void JunitReporter::writeTestCase( TestCaseNode const& testCaseNode ) {
TestCaseStats const& stats = testCaseNode.value;
// All test cases have exactly one section - which represents the
@ -156,7 +155,7 @@ namespace Catch {
writeSection( className, "", rootSection );
}
void writeSection( std::string const& className,
void JunitReporter::writeSection( std::string const& className,
std::string const& rootName,
SectionNode const& sectionNode ) {
std::string name = trim( sectionNode.stats.sectionInfo.name );
@ -191,11 +190,12 @@ namespace Catch {
writeSection( className, name, *childNode );
}
void writeAssertions( SectionNode const& sectionNode ) {
void JunitReporter::writeAssertions( SectionNode const& sectionNode ) {
for( auto const& assertion : sectionNode.assertions )
writeAssertion( assertion );
}
void writeAssertion( AssertionStats const& stats ) {
void JunitReporter::writeAssertion( AssertionStats const& stats ) {
AssertionResult const& result = stats.assertionResult;
if( !result.isOk() ) {
std::string elementName;
@ -242,15 +242,6 @@ namespace Catch {
}
}
XmlWriter xml;
Timer suiteTimer;
std::ostringstream stdOutForSuite;
std::ostringstream stdErrForSuite;
unsigned int unexpectedExceptions = 0;
bool m_okToFail = false;
};
JunitReporter::~JunitReporter() {}
CATCH_REGISTER_REPORTER( "junit", JunitReporter )
} // end namespace Catch

View File

@ -0,0 +1,61 @@
/*
* Created by Martin on 14/11/2017.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef TWOBLUECUBES_CATCH_REPORTER_JUNIT_H_INCLUDED
#define TWOBLUECUBES_CATCH_REPORTER_JUNIT_H_INCLUDED
#include "catch_reporter_bases.hpp"
#include "../internal/catch_xmlwriter.h"
#include "../internal/catch_timer.h"
namespace Catch {
class JunitReporter : public CumulativeReporterBase<JunitReporter> {
public:
JunitReporter(ReporterConfig const& _config);
~JunitReporter() override;
static std::string getDescription();
void noMatchingTestCases(std::string const& /*spec*/) override;
void testRunStarting(TestRunInfo const& runInfo) override;
void testGroupStarting(GroupInfo const& groupInfo) override;
void testCaseStarting(TestCaseInfo const& testCaseInfo) override;
bool assertionEnded(AssertionStats const& assertionStats) override;
void testCaseEnded(TestCaseStats const& testCaseStats) override;
void testGroupEnded(TestGroupStats const& testGroupStats) override;
void testRunEndedCumulative() override;
void writeGroup(TestGroupNode const& groupNode, double suiteTime);
void writeTestCase(TestCaseNode const& testCaseNode);
void writeSection(std::string const& className,
std::string const& rootName,
SectionNode const& sectionNode);
void writeAssertions(SectionNode const& sectionNode);
void writeAssertion(AssertionStats const& stats);
XmlWriter xml;
Timer suiteTimer;
std::string stdOutForSuite;
std::string stdErrForSuite;
unsigned int unexpectedExceptions = 0;
bool m_okToFail = false;
};
} // end namespace Catch
#endif // TWOBLUECUBES_CATCH_REPORTER_JUNIT_H_INCLUDED