1 // ////////////////////////////////////////////////////////////////////////// 2 // Header file HelperMacros.h 3 // (c)Copyright 2000, Baptiste Lepilleur. 4 // Created: 2001/04/15 5 // ////////////////////////////////////////////////////////////////////////// 6 #ifndef CPPUNIT_EXTENSIONS_HELPERMACROS_H 7 #define CPPUNIT_EXTENSIONS_HELPERMACROS_H 8 9 #include <cppunit/TestCaller.h> 10 #include <cppunit/TestSuite.h> 11 #include <cppunit/extensions/AutoRegisterSuite.h> 12 #include <cppunit/extensions/ExceptionTestCaseDecorator.h> 13 #include <cppunit/extensions/TestFixtureFactory.h> 14 #include <cppunit/extensions/TestNamer.h> 15 #include <cppunit/extensions/TestSuiteBuilderContext.h> 16 #include <memory> 17 18 19 /*! \addtogroup WritingTestFixture Writing test fixture 20 */ 21 /** @{ 22 */ 23 24 25 /** \file 26 * Macros intended to ease the definition of test suites. 27 * 28 * The macros 29 * CPPUNIT_TEST_SUITE(), CPPUNIT_TEST(), and CPPUNIT_TEST_SUITE_END() 30 * are designed to facilitate easy creation of a test suite. 31 * For example, 32 * 33 * \code 34 * #include <cppunit/extensions/HelperMacros.h> 35 * class MyTest : public CppUnit::TestFixture { 36 * CPPUNIT_TEST_SUITE( MyTest ); 37 * CPPUNIT_TEST( testEquality ); 38 * CPPUNIT_TEST( testSetName ); 39 * CPPUNIT_TEST_SUITE_END(); 40 * public: 41 * void testEquality(); 42 * void testSetName(); 43 * }; 44 * \endcode 45 * 46 * The effect of these macros is to define two methods in the 47 * class MyTest. The first method is an auxiliary function 48 * named registerTests that you will not need to call directly. 49 * The second function 50 * \code static CppUnit::TestSuite *suite()\endcode 51 * returns a pointer to the suite of tests defined by the CPPUNIT_TEST() 52 * macros. 53 * 54 * Rather than invoking suite() directly, 55 * the macro CPPUNIT_TEST_SUITE_REGISTRATION() is 56 * used to create a static variable that automatically 57 * registers its test suite in a global registry. 58 * The registry yields a Test instance containing all the 59 * registered suites. 60 * \code 61 * CPPUNIT_TEST_SUITE_REGISTRATION( MyTest ); 62 * CppUnit::Test* tp = 63 * CppUnit::TestFactoryRegistry::getRegistry().makeTest(); 64 * \endcode 65 * 66 * The test suite macros can even be used with templated test classes. 67 * For example: 68 * 69 * \code 70 * template<typename CharType> 71 * class StringTest : public CppUnit::TestFixture { 72 * CPPUNIT_TEST_SUITE( StringTest ); 73 * CPPUNIT_TEST( testAppend ); 74 * CPPUNIT_TEST_SUITE_END(); 75 * public: 76 * ... 77 * }; 78 * \endcode 79 * 80 * You need to add in an implementation file: 81 * 82 * \code 83 * CPPUNIT_TEST_SUITE_REGISTRATION( StringTest<char> ); 84 * CPPUNIT_TEST_SUITE_REGISTRATION( StringTest<wchar_t> ); 85 * \endcode 86 */ 87 88 89 /*! \brief Begin test suite 90 * 91 * This macro starts the declaration of a new test suite. 92 * Use CPPUNIT_TEST_SUB_SUITE() instead, if you wish to include the 93 * test suite of the parent class. 94 * 95 * \param ATestFixtureType Type of the test case class. This type \b MUST 96 * be derived from TestFixture. 97 * \see CPPUNIT_TEST_SUB_SUITE, CPPUNIT_TEST, CPPUNIT_TEST_SUITE_END, 98 * \see CPPUNIT_TEST_SUITE_REGISTRATION, CPPUNIT_TEST_EXCEPTION, CPPUNIT_TEST_FAIL. 99 */ 100 #define CPPUNIT_TEST_SUITE( ATestFixtureType ) \ 101 public: \ 102 typedef ATestFixtureType TestFixtureType; \ 103 \ 104 private: \ 105 static const CPPUNIT_NS::TestNamer &getTestNamer__() \ 106 { \ 107 static CPPUNIT_TESTNAMER_DECL( testNamer, ATestFixtureType ); \ 108 return testNamer; \ 109 } \ 110 \ 111 public: \ 112 typedef CPPUNIT_NS::TestSuiteBuilderContext<TestFixtureType> \ 113 TestSuiteBuilderContextType; \ 114 \ 115 static void \ 116 addTestsToSuite( CPPUNIT_NS::TestSuiteBuilderContextBase &baseContext ) \ 117 { \ 118 TestSuiteBuilderContextType context( baseContext ) 119 120 121 /*! \brief Begin test suite (includes parent suite) 122 * 123 * This macro may only be used in a class whose parent class 124 * defines a test suite using CPPUNIT_TEST_SUITE() or CPPUNIT_TEST_SUB_SUITE(). 125 * 126 * This macro begins the declaration of a test suite, in the same 127 * manner as CPPUNIT_TEST_SUITE(). In addition, the test suite of the 128 * parent is automatically inserted in the test suite being 129 * defined. 130 * 131 * Here is an example: 132 * 133 * \code 134 * #include <cppunit/extensions/HelperMacros.h> 135 * class MySubTest : public MyTest { 136 * CPPUNIT_TEST_SUB_SUITE( MySubTest, MyTest ); 137 * CPPUNIT_TEST( testAdd ); 138 * CPPUNIT_TEST( testSub ); 139 * CPPUNIT_TEST_SUITE_END(); 140 * public: 141 * void testAdd(); 142 * void testSub(); 143 * }; 144 * \endcode 145 * 146 * \param ATestFixtureType Type of the test case class. This type \b MUST 147 * be derived from TestFixture. 148 * \param ASuperClass Type of the parent class. 149 * \see CPPUNIT_TEST_SUITE. 150 */ 151 #define CPPUNIT_TEST_SUB_SUITE( ATestFixtureType, ASuperClass ) \ 152 public: \ 153 typedef ASuperClass ParentTestFixtureType; \ 154 private: \ 155 CPPUNIT_TEST_SUITE( ATestFixtureType ); \ 156 ParentTestFixtureType::addTestsToSuite( baseContext ) 157 158 159 /*! \brief End declaration of the test suite. 160 * 161 * After this macro, member access is set to "private". 162 * 163 * \see CPPUNIT_TEST_SUITE. 164 * \see CPPUNIT_TEST_SUITE_REGISTRATION. 165 */ 166 #define CPPUNIT_TEST_SUITE_END() \ 167 } \ 168 \ 169 public: \ 170 static CPPUNIT_NS::TestSuite *suite() \ 171 { \ 172 const CPPUNIT_NS::TestNamer &namer = getTestNamer__(); \ 173 std::unique_ptr<CPPUNIT_NS::TestSuite> guard( \ 174 new CPPUNIT_NS::TestSuite( namer.getFixtureName() )); \ 175 CPPUNIT_NS::ConcretTestFixtureFactory<TestFixtureType> factory; \ 176 CPPUNIT_NS::TestSuiteBuilderContextBase context( *guard.get(), \ 177 namer, \ 178 factory ); \ 179 TestFixtureType::addTestsToSuite( context ); \ 180 return guard.release(); \ 181 } \ 182 private: /* dummy typedef so that the macro can still end with ';'*/ \ 183 typedef int CppUnitDummyTypedefForSemiColonEnding__ 184 185 /*! \brief End declaration of an abstract test suite. 186 * 187 * Use this macro to indicate that the %TestFixture is abstract. No 188 * static suite() method will be declared. 189 * 190 * After this macro, member access is set to "private". 191 * 192 * Here is an example of usage: 193 * 194 * The abstract test fixture: 195 * \code 196 * #include <cppunit/extensions/HelperMacros.h> 197 * class AbstractDocument; 198 * class AbstractDocumentTest : public CppUnit::TestFixture { 199 * CPPUNIT_TEST_SUITE( AbstractDocumentTest ); 200 * CPPUNIT_TEST( testInsertText ); 201 * CPPUNIT_TEST_SUITE_END_ABSTRACT(); 202 * public: 203 * void testInsertText(); 204 * 205 * void setUp() 206 * { 207 * m_document = makeDocument(); 208 * } 209 * 210 * void tearDown() 211 * { 212 * delete m_document; 213 * } 214 * protected: 215 * virtual AbstractDocument *makeDocument() =0; 216 * 217 * AbstractDocument *m_document; 218 * };\endcode 219 * 220 * The concret test fixture: 221 * \code 222 * class RichTextDocumentTest : public AbstractDocumentTest { 223 * CPPUNIT_TEST_SUB_SUITE( RichTextDocumentTest, AbstractDocumentTest ); 224 * CPPUNIT_TEST( testInsertFormatedText ); 225 * CPPUNIT_TEST_SUITE_END(); 226 * public: 227 * void testInsertFormatedText(); 228 * protected: 229 * AbstractDocument *makeDocument() 230 * { 231 * return new RichTextDocument(); 232 * } 233 * };\endcode 234 * 235 * \see CPPUNIT_TEST_SUB_SUITE. 236 * \see CPPUNIT_TEST_SUITE_REGISTRATION. 237 */ 238 #define CPPUNIT_TEST_SUITE_END_ABSTRACT() \ 239 } \ 240 private: /* dummy typedef so that the macro can still end with ';'*/ \ 241 typedef int CppUnitDummyTypedefForSemiColonEnding__ 242 243 244 /*! \brief Add a test to the suite (for custom test macro). 245 * 246 * The specified test will be added to the test suite being declared. This macro 247 * is intended for \e advanced usage, to extend %CppUnit by creating new macro such 248 * as CPPUNIT_TEST_EXCEPTION()... 249 * 250 * Between macro CPPUNIT_TEST_SUITE() and CPPUNIT_TEST_SUITE_END(), you can assume 251 * that the following variables can be used: 252 * \code 253 * typedef TestSuiteBuilder<TestFixtureType> TestSuiteBuilderType; 254 * TestSuiteBuilderType &context; 255 * \endcode 256 * 257 * \c context can be used to name test case, create new test fixture instance, 258 * or add test case to the test fixture suite. 259 * 260 * Below is an example that show how to use this macro to create new macro to add 261 * test to the fixture suite. The macro below show how you would add a new type 262 * of test case which fails if the execution last more than a given time limit. 263 * It relies on an imaginary TimeOutTestCaller class which has an interface similar 264 * to TestCaller. 265 * 266 * \code 267 * #define CPPUNITEX_TEST_TIMELIMIT( testMethod, timeLimit ) \ 268 * CPPUNIT_TEST_SUITE_ADD_TEST( (new TimeOutTestCaller<TestFixtureType>( \ 269 * namer.getTestNameFor( #testMethod ), \ 270 * &TestFixtureType::testMethod, \ 271 * factory.makeFixture(), \ 272 * timeLimit ) ) ) 273 * 274 * class PerformanceTest : CppUnit::TestFixture 275 * { 276 * public: 277 * CPPUNIT_TEST_SUITE( PerformanceTest ); 278 * CPPUNITEX_TEST_TIMELIMIT( testSortReverseOrder, 5.0 ); 279 * CPPUNIT_TEST_SUITE_END(); 280 * 281 * void testSortReverseOrder(); 282 * }; 283 * \endcode 284 * 285 * \param test Test to add to the suite. Must be a subclass of Test. The test name 286 * should have been obtained using TestNamer::getTestNameFor(). 287 */ 288 #define CPPUNIT_TEST_SUITE_ADD_TEST( test ) \ 289 context.addTest( test ) 290 291 /*! \brief Add a method to the suite. 292 * \param testMethod Name of the method of the test case to add to the 293 * suite. The signature of the method must be of 294 * type: void testMethod(); 295 * \see CPPUNIT_TEST_SUITE. 296 */ 297 #define CPPUNIT_TEST( testMethod ) \ 298 CPPUNIT_TEST_SUITE_ADD_TEST( \ 299 ( new CPPUNIT_NS::TestCaller<TestFixtureType>( \ 300 context.getTestNameFor( #testMethod), \ 301 &TestFixtureType::testMethod, \ 302 context.makeFixture() ) ) ) 303 304 #define CPPUNIT_TEST_PARAMETERIZED( testMethod, ... ) \ 305 for (auto& i : __VA_ARGS__) \ 306 { \ 307 TestFixtureType* fixture = context.makeFixture(); \ 308 CPPUNIT_TEST_SUITE_ADD_TEST( \ 309 ( new CPPUNIT_NS::TestCaller<TestFixtureType>( \ 310 context.getTestNameFor(#testMethod, i), \ 311 std::bind(&TestFixtureType::testMethod, fixture, i), \ 312 fixture))); \ 313 } 314 315 /*! \brief Add a test which fail if the specified exception is not caught. 316 * 317 * Example: 318 * \code 319 * #include <cppunit/extensions/HelperMacros.h> 320 * #include <vector> 321 * class MyTest : public CppUnit::TestFixture { 322 * CPPUNIT_TEST_SUITE( MyTest ); 323 * CPPUNIT_TEST_EXCEPTION( testVectorAtThrow, std::out_of_range ); 324 * CPPUNIT_TEST_SUITE_END(); 325 * public: 326 * void testVectorAtThrow() 327 * { 328 * std::vector<int> v; 329 * v.at( 1 ); // must throw exception std::out_of_range 330 * } 331 * }; 332 * \endcode 333 * 334 * \param testMethod Name of the method of the test case to add to the suite. 335 * \param ExceptionType Type of the exception that must be thrown by the test 336 * method. 337 * \deprecated Use the assertion macro CPPUNIT_ASSERT_THROW instead. 338 */ 339 #define CPPUNIT_TEST_EXCEPTION( testMethod, ExceptionType ) \ 340 CPPUNIT_TEST_SUITE_ADD_TEST( \ 341 (new CPPUNIT_NS::ExceptionTestCaseDecorator< ExceptionType >( \ 342 new CPPUNIT_NS::TestCaller< TestFixtureType >( \ 343 context.getTestNameFor( #testMethod ), \ 344 &TestFixtureType::testMethod, \ 345 context.makeFixture() ) ) ) ) 346 347 /*! \brief Adds a test case which is excepted to fail. 348 * 349 * The added test case expect an assertion to fail. You usually used that type 350 * of test case when testing custom assertion macros. 351 * 352 * \code 353 * CPPUNIT_TEST_FAIL( testAssertFalseFail ); 354 * 355 * void testAssertFalseFail() 356 * { 357 * CPPUNIT_ASSERT( false ); 358 * } 359 * \endcode 360 * \see CreatingNewAssertions. 361 * \deprecated Use the assertion macro CPPUNIT_ASSERT_ASSERTION_FAIL instead. 362 */ 363 #define CPPUNIT_TEST_FAIL( testMethod ) \ 364 CPPUNIT_TEST_EXCEPTION( testMethod, CPPUNIT_NS::Exception ) 365 366 /*! \brief Adds some custom test cases. 367 * 368 * Use this to add one or more test cases to the fixture suite. The specified 369 * method is called with a context parameter that can be used to name, 370 * instantiate fixture, and add instantiated test case to the fixture suite. 371 * The specified method must have the following signature: 372 * \code 373 * static void aMethodName( TestSuiteBuilderContextType &context ); 374 * \endcode 375 * 376 * \c TestSuiteBuilderContextType is typedef to 377 * TestSuiteBuilderContext<TestFixtureType> declared by CPPUNIT_TEST_SUITE(). 378 * 379 * Here is an example that add two custom tests: 380 * 381 * \code 382 * #include <cppunit/extensions/HelperMacros.h> 383 * 384 * class MyTest : public CppUnit::TestFixture { 385 * CPPUNIT_TEST_SUITE( MyTest ); 386 * CPPUNIT_TEST_SUITE_ADD_CUSTOM_TESTS( addTimeOutTests ); 387 * CPPUNIT_TEST_SUITE_END(); 388 * public: 389 * static void addTimeOutTests( TestSuiteBuilderContextType &context ) 390 * { 391 * context.addTest( new TimeOutTestCaller( context.getTestNameFor( "test1" ) ), 392 * &MyTest::test1, 393 * context.makeFixture(), 394 * 5.0 ); 395 * context.addTest( new TimeOutTestCaller( context.getTestNameFor( "test2" ) ), 396 * &MyTest::test2, 397 * context.makeFixture(), 398 * 5.0 ); 399 * } 400 * 401 * void test1() 402 * { 403 * // Do some test that may never end... 404 * } 405 * 406 * void test2() 407 * { 408 * // Do some test that may never end... 409 * } 410 * }; 411 * \endcode 412 * @param testAdderMethod Name of the method called to add the test cases. 413 */ 414 #define CPPUNIT_TEST_SUITE_ADD_CUSTOM_TESTS( testAdderMethod ) \ 415 testAdderMethod( context ) 416 417 /*! \brief Adds a property to the test suite builder context. 418 * \param APropertyKey Key of the property to add. 419 * \param APropertyValue Value for the added property. 420 * Example: 421 * \code 422 * CPPUNIT_TEST_SUITE_PROPERTY("XmlFileName", "paraTest.xml"); \endcode 423 */ 424 #define CPPUNIT_TEST_SUITE_PROPERTY( APropertyKey, APropertyValue ) \ 425 context.addProperty( std::string(APropertyKey), \ 426 std::string(APropertyValue) ) 427 428 /** @} 429 */ 430 431 432 /*! Adds the specified fixture suite to the unnamed registry. 433 * \ingroup CreatingTestSuite 434 * 435 * This macro declares a static variable whose construction 436 * causes a test suite factory to be inserted in a global registry 437 * of such factories. The registry is available by calling 438 * the static function CppUnit::TestFactoryRegistry::getRegistry(). 439 * 440 * \param ATestFixtureType Type of the test case class. 441 * \warning This macro should be used only once per line of code (the line 442 * number is used to name a hidden static variable). 443 * \see CPPUNIT_TEST_SUITE_NAMED_REGISTRATION 444 * \see CPPUNIT_REGISTRY_ADD_TO_DEFAULT 445 * \see CPPUNIT_REGISTRY_ADD 446 * \see CPPUNIT_TEST_SUITE, CppUnit::AutoRegisterSuite, 447 * CppUnit::TestFactoryRegistry. 448 */ 449 #define CPPUNIT_TEST_SUITE_REGISTRATION( ATestFixtureType ) \ 450 static CPPUNIT_NS::AutoRegisterSuite< ATestFixtureType > \ 451 CPPUNIT_MAKE_UNIQUE_NAME(autoRegisterRegistry__ ) 452 453 454 /** Adds the specified fixture suite to the specified registry suite. 455 * \ingroup CreatingTestSuite 456 * 457 * This macro declares a static variable whose construction 458 * causes a test suite factory to be inserted in the global registry 459 * suite of the specified name. The registry is available by calling 460 * the static function CppUnit::TestFactoryRegistry::getRegistry(). 461 * 462 * For the suite name, use a string returned by a static function rather 463 * than a hardcoded string. That way, you can know what are the name of 464 * named registry and you don't risk mistyping the registry name. 465 * 466 * \code 467 * // MySuites.h 468 * namespace MySuites { 469 * std::string math() { 470 * return "Math"; 471 * } 472 * } 473 * 474 * // ComplexNumberTest.cpp 475 * #include "MySuites.h" 476 * 477 * CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ComplexNumberTest, MySuites::math() ); 478 * \endcode 479 * 480 * \param ATestFixtureType Type of the test case class. 481 * \param suiteName Name of the global registry suite the test suite is 482 * registered into. 483 * \warning This macro should be used only once per line of code (the line 484 * number is used to name a hidden static variable). 485 * \see CPPUNIT_TEST_SUITE_REGISTRATION 486 * \see CPPUNIT_REGISTRY_ADD_TO_DEFAULT 487 * \see CPPUNIT_REGISTRY_ADD 488 * \see CPPUNIT_TEST_SUITE, CppUnit::AutoRegisterSuite, 489 * CppUnit::TestFactoryRegistry.. 490 */ 491 #define CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ATestFixtureType, suiteName ) \ 492 static CPPUNIT_NS::AutoRegisterSuite< ATestFixtureType > \ 493 CPPUNIT_MAKE_UNIQUE_NAME(autoRegisterRegistry__ )(suiteName) 494 495 /*! Adds that the specified registry suite to another registry suite. 496 * \ingroup CreatingTestSuite 497 * 498 * Use this macros to automatically create test registry suite hierarchy. For example, 499 * if you want to create the following hierarchy: 500 * - Math 501 * - IntegerMath 502 * - FloatMath 503 * - FastFloat 504 * - StandardFloat 505 * 506 * You can do this automatically with: 507 * \code 508 * CPPUNIT_REGISTRY_ADD( "FastFloat", "FloatMath" ); 509 * CPPUNIT_REGISTRY_ADD( "IntegerMath", "Math" ); 510 * CPPUNIT_REGISTRY_ADD( "FloatMath", "Math" ); 511 * CPPUNIT_REGISTRY_ADD( "StandardFloat", "FloatMath" ); 512 * \endcode 513 * 514 * There is no specific order of declaration. Think of it as declaring links. 515 * 516 * You register the test in each suite using CPPUNIT_TEST_SUITE_NAMED_REGISTRATION. 517 * 518 * \param which Name of the registry suite to add to the registry suite named \a to. 519 * \param to Name of the registry suite \a which is added to. 520 * \see CPPUNIT_REGISTRY_ADD_TO_DEFAULT, CPPUNIT_TEST_SUITE_NAMED_REGISTRATION. 521 */ 522 #define CPPUNIT_REGISTRY_ADD( which, to ) \ 523 static CPPUNIT_NS::AutoRegisterRegistry \ 524 CPPUNIT_MAKE_UNIQUE_NAME( autoRegisterRegistry__ )( which, to ) 525 526 /*! Adds that the specified registry suite to the default registry suite. 527 * \ingroup CreatingTestSuite 528 * 529 * This macro is just like CPPUNIT_REGISTRY_ADD except the specified registry 530 * suite is added to the default suite (root suite). 531 * 532 * \param which Name of the registry suite to add to the default registry suite. 533 * \see CPPUNIT_REGISTRY_ADD. 534 */ 535 #define CPPUNIT_REGISTRY_ADD_TO_DEFAULT( which ) \ 536 static CPPUNIT_NS::AutoRegisterRegistry \ 537 CPPUNIT_MAKE_UNIQUE_NAME( autoRegisterRegistry__ )( which ) 538 539 // Backwards compatibility 540 // (Not tested!) 541 542 #if CPPUNIT_ENABLE_CU_TEST_MACROS 543 544 #define CU_TEST_SUITE(tc) CPPUNIT_TEST_SUITE(tc) 545 #define CU_TEST_SUB_SUITE(tc,sc) CPPUNIT_TEST_SUB_SUITE(tc,sc) 546 #define CU_TEST(tm) CPPUNIT_TEST(tm) 547 #define CU_TEST_SUITE_END() CPPUNIT_TEST_SUITE_END() 548 #define CU_TEST_SUITE_REGISTRATION(tc) CPPUNIT_TEST_SUITE_REGISTRATION(tc) 549 550 #endif 551 552 553 #endif // CPPUNIT_EXTENSIONS_HELPERMACROS_H 554