1 #include "UnitTest++/UnitTestPP.h" 2 #include "RecordingReporter.h" 3 #include "UnitTest++/ReportAssert.h" 4 #include "UnitTest++/TestList.h" 5 #include "UnitTest++/TimeHelpers.h" 6 #include "UnitTest++/TimeConstraint.h" 7 #include "UnitTest++/ReportAssertImpl.h" 8 9 using namespace UnitTest; 10 11 namespace 12 { 13 14 struct MockTest : public Test 15 { 16 MockTest(char const* testName, bool const success_, bool const assert_, int const count_ = 1) 17 : Test(testName) 18 , success(success_) 19 , asserted(assert_) 20 , count(count_) 21 { 22 } 23 24 virtual void RunImpl() const 25 { 26 TestResults& testResults_ = *CurrentTest::Results(); 27 28 for (int i=0; i < count; ++i) 29 { 30 if (asserted) 31 { 32 ReportAssert("desc", "file", 0); 33 } 34 else if (!success) 35 { 36 testResults_.OnTestFailure(m_details, "message"); 37 } 38 } 39 } 40 41 bool const success; 42 bool const asserted; 43 int const count; 44 }; 45 46 struct FixtureBase 47 { 48 FixtureBase() 49 : runner(reporter) 50 { 51 } 52 53 template <class Predicate> 54 int RunTestsIf(TestList const& list, char const* suiteName, 55 const Predicate& predicate, int maxTestTimeInMs) 56 { 57 TestResults* oldResults = CurrentTest::Results(); 58 const TestDetails* oldDetails = CurrentTest::Details(); 59 int result = runner.RunTestsIf(list, suiteName, predicate, maxTestTimeInMs); 60 CurrentTest::Results() = oldResults; 61 CurrentTest::Details() = oldDetails; 62 return result; 63 } 64 65 TestRunner runner; 66 RecordingReporter reporter; 67 }; 68 69 struct TestRunnerFixture : public FixtureBase 70 { 71 TestList list; 72 }; 73 74 TEST_FIXTURE(TestRunnerFixture, TestStartIsReportedCorrectly) 75 { 76 MockTest test("goodtest", true, false); 77 list.Add(&test); 78 79 RunTestsIf(list, NULL, True(), 0); 80 CHECK_EQUAL(1, reporter.testRunCount); 81 CHECK_EQUAL("goodtest", reporter.lastStartedTest); 82 } 83 84 TEST_FIXTURE(TestRunnerFixture, TestFinishIsReportedCorrectly) 85 { 86 MockTest test("goodtest", true, false); 87 list.Add(&test); 88 89 RunTestsIf(list, NULL, True(), 0); 90 CHECK_EQUAL(1, reporter.testFinishedCount); 91 CHECK_EQUAL("goodtest", reporter.lastFinishedTest); 92 } 93 94 class SlowTest : public Test 95 { 96 public: 97 SlowTest() 98 : Test("slow", "somesuite", "filename", 123) 99 { 100 } 101 102 virtual void RunImpl() const 103 { 104 TimeHelpers::SleepMs(20); 105 } 106 }; 107 108 TEST_FIXTURE(TestRunnerFixture, TestFinishIsCalledWithCorrectTime) 109 { 110 SlowTest test; 111 list.Add(&test); 112 113 RunTestsIf(list, NULL, True(), 0); 114 CHECK(reporter.lastFinishedTestTime >= 0.005f && reporter.lastFinishedTestTime <= 0.050f); 115 } 116 117 TEST_FIXTURE(TestRunnerFixture, FailureCountIsZeroWhenNoTestsAreRun) 118 { 119 CHECK_EQUAL(0, RunTestsIf(list, NULL, True(), 0)); 120 CHECK_EQUAL(0, reporter.testRunCount); 121 CHECK_EQUAL(0, reporter.testFailedCount); 122 } 123 124 TEST_FIXTURE(TestRunnerFixture, CallsReportFailureOncePerFailingTest) 125 { 126 MockTest test1("test", false, false); 127 list.Add(&test1); 128 MockTest test2("test", true, false); 129 list.Add(&test2); 130 MockTest test3("test", false, false); 131 list.Add(&test3); 132 133 CHECK_EQUAL(2, RunTestsIf(list, NULL, True(), 0)); 134 CHECK_EQUAL(2, reporter.testFailedCount); 135 } 136 137 TEST_FIXTURE(TestRunnerFixture, TestsThatAssertAreReportedAsFailing) 138 { 139 MockTest test("test", true, true); 140 list.Add(&test); 141 142 RunTestsIf(list, NULL, True(), 0); 143 CHECK_EQUAL(1, reporter.testFailedCount); 144 } 145 146 147 TEST_FIXTURE(TestRunnerFixture, ReporterNotifiedOfTestCount) 148 { 149 MockTest test1("test", true, false); 150 MockTest test2("test", true, false); 151 MockTest test3("test", true, false); 152 list.Add(&test1); 153 list.Add(&test2); 154 list.Add(&test3); 155 156 RunTestsIf(list, NULL, True(), 0); 157 CHECK_EQUAL(3, reporter.summaryTotalTestCount); 158 } 159 160 TEST_FIXTURE(TestRunnerFixture, ReporterNotifiedOfFailedTests) 161 { 162 MockTest test1("test", false, false, 2); 163 MockTest test2("test", true, false); 164 MockTest test3("test", false, false, 3); 165 list.Add(&test1); 166 list.Add(&test2); 167 list.Add(&test3); 168 169 RunTestsIf(list, NULL, True(), 0); 170 CHECK_EQUAL(2, reporter.summaryFailedTestCount); 171 } 172 173 TEST_FIXTURE(TestRunnerFixture, ReporterNotifiedOfFailures) 174 { 175 MockTest test1("test", false, false, 2); 176 MockTest test2("test", true, false); 177 MockTest test3("test", false, false, 3); 178 list.Add(&test1); 179 list.Add(&test2); 180 list.Add(&test3); 181 182 RunTestsIf(list, NULL, True(), 0); 183 CHECK_EQUAL(5, reporter.summaryFailureCount); 184 } 185 186 TEST_FIXTURE(TestRunnerFixture, SlowTestPassesForHighTimeThreshold) 187 { 188 SlowTest test; 189 list.Add(&test); 190 191 RunTestsIf(list, NULL, True(), 0); 192 CHECK_EQUAL(0, reporter.testFailedCount); 193 } 194 195 TEST_FIXTURE(TestRunnerFixture, SlowTestFailsForLowTimeThreshold) 196 { 197 SlowTest test; 198 list.Add(&test); 199 200 RunTestsIf(list, NULL, True(), 3); 201 CHECK_EQUAL(1, reporter.testFailedCount); 202 } 203 204 TEST_FIXTURE(TestRunnerFixture, SlowTestHasCorrectFailureInformation) 205 { 206 SlowTest test; 207 list.Add(&test); 208 209 RunTestsIf(list, NULL, True(), 3); 210 211 using namespace std; 212 213 CHECK_EQUAL(test.m_details.testName, reporter.lastFailedTest); 214 CHECK(strstr(test.m_details.filename, reporter.lastFailedFile)); 215 CHECK_EQUAL(test.m_details.lineNumber, reporter.lastFailedLine); 216 217 CHECK(strstr(reporter.lastFailedMessage, "Global time constraint failed")); 218 CHECK(strstr(reporter.lastFailedMessage, "3ms")); 219 } 220 221 TEST_FIXTURE(TestRunnerFixture, SlowTestWithTimeExemptionPasses) 222 { 223 class SlowExemptedTest : public Test 224 { 225 public: 226 SlowExemptedTest() : Test("slowexempted", "", 0) {} 227 virtual void RunImpl() const 228 { 229 UNITTEST_TIME_CONSTRAINT_EXEMPT(); 230 TimeHelpers::SleepMs(20); 231 } 232 }; 233 234 SlowExemptedTest test; 235 list.Add(&test); 236 237 RunTestsIf(list, NULL, True(), 3); 238 CHECK_EQUAL(0, reporter.testFailedCount); 239 } 240 241 struct TestSuiteFixture : FixtureBase 242 { 243 TestSuiteFixture() 244 : test1("TestInDefaultSuite") 245 , test2("TestInOtherSuite", "OtherSuite") 246 , test3("SecondTestInDefaultSuite") 247 { 248 list.Add(&test1); 249 list.Add(&test2); 250 } 251 252 Test test1; 253 Test test2; 254 Test test3; 255 TestList list; 256 }; 257 258 TEST_FIXTURE(TestSuiteFixture, TestRunnerRunsAllSuitesIfNullSuiteIsPassed) 259 { 260 RunTestsIf(list, NULL, True(), 0); 261 CHECK_EQUAL(2, reporter.summaryTotalTestCount); 262 } 263 264 TEST_FIXTURE(TestSuiteFixture,TestRunnerRunsOnlySpecifiedSuite) 265 { 266 RunTestsIf(list, "OtherSuite", True(), 0); 267 CHECK_EQUAL(1, reporter.summaryTotalTestCount); 268 CHECK_EQUAL("TestInOtherSuite", reporter.lastFinishedTest); 269 } 270 271 struct RunTestIfNameIs 272 { 273 RunTestIfNameIs(char const* name_) 274 : name(name_) 275 { 276 } 277 278 bool operator()(const Test* const test) const 279 { 280 using namespace std; 281 return (0 == strcmp(test->m_details.testName, name)); 282 } 283 284 char const* name; 285 }; 286 287 TEST(TestMockPredicateBehavesCorrectly) 288 { 289 RunTestIfNameIs predicate("pass"); 290 291 Test pass("pass"); 292 Test fail("fail"); 293 294 CHECK(predicate(&pass)); 295 CHECK(!predicate(&fail)); 296 } 297 298 TEST_FIXTURE(TestRunnerFixture, TestRunnerRunsTestsThatPassPredicate) 299 { 300 Test should_run("goodtest"); 301 list.Add(&should_run); 302 303 Test should_not_run("badtest"); 304 list.Add(&should_not_run); 305 306 RunTestsIf(list, NULL, RunTestIfNameIs("goodtest"), 0); 307 CHECK_EQUAL(1, reporter.testRunCount); 308 CHECK_EQUAL("goodtest", reporter.lastStartedTest); 309 } 310 311 TEST_FIXTURE(TestRunnerFixture, TestRunnerOnlyRunsTestsInSpecifiedSuiteAndThatPassPredicate) 312 { 313 Test runningTest1("goodtest", "suite"); 314 Test skippedTest2("goodtest"); 315 Test skippedTest3("badtest", "suite"); 316 Test skippedTest4("badtest"); 317 318 list.Add(&runningTest1); 319 list.Add(&skippedTest2); 320 list.Add(&skippedTest3); 321 list.Add(&skippedTest4); 322 323 RunTestsIf(list, "suite", RunTestIfNameIs("goodtest"), 0); 324 325 CHECK_EQUAL(1, reporter.testRunCount); 326 CHECK_EQUAL("goodtest", reporter.lastStartedTest); 327 CHECK_EQUAL("suite", reporter.lastStartedSuite); 328 } 329 330 }