1 // 207-Rpt-TeamCityReporter.cpp 2 3 // Catch has built-in and external reporters: 4 // Built-in: 5 // - compact 6 // - console 7 // - junit 8 // - xml 9 // External: 10 // - automake 11 // - tap 12 // - teamcity (this example) 13 14 // main() and reporter code provided in 200-Rpt-CatchMain.cpp 15 16 #include <catch2/catch.hpp> 17 18 #ifdef _MSC_VER 19 # pragma warning (disable : 4702) // Disable warning: unreachable code 20 #endif 21 22 TEST_CASE( "TeamCity passes unconditionally succeeding assertion", "[teamcity]" ) { 23 24 SUCCEED(); 25 } 26 27 TEST_CASE( "TeamCity reports unconditionally failing assertion", "[teamcity]" ) { 28 29 FAIL(); 30 } 31 32 TEST_CASE( "TeamCity reports failing check", "[teamcity]" ) { 33 34 REQUIRE( 3 == 7 ); 35 } 36 37 TEST_CASE( "TeamCity reports failing check-false", "[teamcity]" ) { 38 39 REQUIRE_FALSE( 3 == 3 ); 40 } 41 42 TEST_CASE( "TeamCity reports failing check-that", "[teamcity]" ) { 43 44 using namespace Catch; 45 46 REQUIRE_THAT( "hello", Contains( "world" ) ); 47 } 48 49 TEST_CASE( "TeamCity reports unexpected exception", "[teamcity]" ) { 50 51 REQUIRE( (throw std::runtime_error("surprise!"), true) ); 52 } 53 54 TEST_CASE( "TeamCity reports undesired exception", "[teamcity]" ) { 55 56 REQUIRE_NOTHROW( (throw std::runtime_error("surprise!"), true) ); 57 } 58 59 TEST_CASE( "TeamCity reports missing expected exception", "[teamcity]" ) { 60 61 REQUIRE_THROWS( true ); 62 } 63 64 TEST_CASE( "TeamCity reports missing specific expected exception", "[teamcity]" ) { 65 66 REQUIRE_THROWS_AS( throw std::bad_alloc(), std::runtime_error ); 67 } 68 69 TEST_CASE( "TeamCity reports unexpected message in expected exception", "[teamcity]" ) { 70 71 using namespace Catch; 72 73 CHECK_THROWS_WITH( throw std::runtime_error("hello"), "world" ); 74 CHECK_THROWS_WITH( throw std::runtime_error("hello"), Contains("world") ); 75 } 76 77 struct MyException: public std::runtime_error 78 { MyExceptionMyException79 MyException( char const * text ) 80 : std::runtime_error( text ) {} 81 82 ~MyException() override; 83 }; 84 85 // prevent -Wweak-vtables: 86 MyException::~MyException() = default; 87 88 struct MyExceptionMatcher : Catch::MatcherBase< std::runtime_error > 89 { 90 std::string m_text; 91 MyExceptionMatcherMyExceptionMatcher92 MyExceptionMatcher( char const * text ) 93 : m_text( text ) 94 {} 95 96 ~MyExceptionMatcher() override; 97 matchMyExceptionMatcher98 bool match( std::runtime_error const & arg ) const override 99 { 100 return m_text == arg.what() ; 101 } 102 describeMyExceptionMatcher103 std::string describe() const override 104 { 105 return "it's me"; 106 } 107 }; 108 109 // prevent -Wweak-vtables: 110 MyExceptionMatcher::~MyExceptionMatcher() = default; 111 112 TEST_CASE( "TeamCity failing check-throws-matches", "[teamcity]" ) { 113 114 CHECK_THROWS_MATCHES( throw MyException("hello"), MyException, MyExceptionMatcher("world") ); 115 } 116 117 // [!throws] - lets Catch know that this test is likely to throw an exception even if successful. 118 // This causes the test to be excluded when running with -e or --nothrow. 119 120 // No special effects for the reporter. 121 122 TEST_CASE( "TeamCity throwing exception with tag [!throws]", "[teamcity][!throws]" ) { 123 124 REQUIRE_THROWS( throw std::runtime_error("unsurprisingly") ); 125 } 126 127 // [!mayfail] - doesn't fail the test if any given assertion fails (but still reports it). This can be useful to flag a work-in-progress, or a known issue that you don't want to immediately fix but still want to track in your tests. 128 129 TEST_CASE( "TeamCity failing assertion with tag [!mayfail]", "[teamcity][!mayfail] " ) { 130 131 REQUIRE( 3 == 7 ); // doesn't fail test case this time, reports: testIgnored 132 REQUIRE( 3 == 3 ); 133 } 134 135 // [!shouldfail] - like [!mayfail] but fails the test if it passes. 136 // This can be useful if you want to be notified of accidental, or third-party, fixes. 137 138 TEST_CASE( "TeamCity succeeding assertion with tag [!shouldfail]", "[teamcity][!shouldfail]" ) { 139 140 SUCCEED( "Marked [!shouldfail]" ); 141 } 142 143 // Compile & run: 144 // - g++ -std=c++11 -Wall -I$(CATCH_ROOT) -DCATCH_EXAMPLE_RPT_1=\"include/reporters/catch_reporter_teamcity.hpp\" -o 200-Rpt-CatchMainTeamCity.o -c 200-Rpt-CatchMain.cpp 145 // - g++ -std=c++11 -Wall -I$(CATCH_ROOT) -o 207-Rpt-TeamCityReporter 207-Rpt-TeamCityReporter.cpp 200-Rpt-CatchMainTeamCity.o && 207-Rpt-TeamCityReporter --list-reporters 146 // 147 // - cl -EHsc -I%CATCH_ROOT% -DCATCH_EXAMPLE_RPT_1=\"include/reporters/catch_reporter_teamcity.hpp\" -Fo200-Rpt-CatchMainTeamCity.obj -c 200-Rpt-CatchMain.cpp 148 // - cl -EHsc -I%CATCH_ROOT% 207-Rpt-TeamCityReporter.cpp 200-Rpt-CatchMainTeamCity.o && 207-Rpt-TeamCityReporter --list-reporters 149 150 // Compilation output (--list-reporters): 151 // Available reporters: 152 // compact: Reports test results on a single line, suitable for IDEs 153 // console: Reports test results as plain lines of text 154 // junit: Reports test results in an XML format that looks like Ant's 155 // junitreport target 156 // teamcity: Reports test results as TeamCity service messages 157 // xml: Reports test results as an XML document 158 159 // Expected output (abbreviated and broken into shorter lines): 160 // 161 // prompt> 207-Rpt-TeamCityReporter.exe --reporter teamcity 162 // ##teamcity[testSuiteStarted name='207-Rpt-TeamCityReporter.exe'] 163 // ##teamcity[testStarted name='TeamCity passes unconditionally succeeding assertion'] 164 // ##teamcity[testFinished name='TeamCity passes unconditionally succeeding assertion' duration='1'] 165 // ##teamcity[testStarted name='TeamCity reports unconditionally failing assertion'] 166 // ##teamcity[testFailed name='TeamCity reports unconditionally failing assertion' / 167 // message='.../examples/207-Rpt-TeamCityReporter.cpp:23|n/ 168 // ...............................................................................|n|n/ 169 // .../examples/207-Rpt-TeamCityReporter.cpp:25|nexplicit failure'] 170 // ##teamcity[testFinished name='TeamCity reports unconditionally failing assertion' duration='3'] 171 // ... 172