unitTesting.cpp
Engine/source/testing/unitTesting.cpp
Detailed Description
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2014 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#ifdef TORQUE_TESTS_ENABLED 25 26#include "console/engineAPI.h" 27#include "console/consoleInternal.h" 28#include "unitTesting.h" 29#include "memoryTester.h" 30 31#include <gtest/gtest-all.cc> 32 33//----------------------------------------------------------------------------- 34 35class TorqueUnitTestListener : public ::testing::EmptyTestEventListener 36{ 37 // Called before a test starts. 38 virtual void OnTestStart( const ::testing::TestInfo& testInfo ) 39 { 40 if( mVerbose ) 41 Con::printf("> Starting Test '%s.%s'", 42 testInfo.test_case_name(), testInfo.name()); 43 } 44 45 // Called after a failed assertion or a SUCCEED() invocation. 46 virtual void OnTestPartResult( const ::testing::TestPartResult& testPartResult ) 47 { 48 if ( testPartResult.failed() ) 49 { 50 Con::warnf(">> Failed with '%s' in '%s' at (line:%d)\n", 51 testPartResult.summary(), 52 testPartResult.file_name(), 53 testPartResult.line_number() 54 ); 55 } 56 else if( mVerbose ) 57 { 58 Con::printf(">> Passed with '%s' in '%s' at (line:%d)", 59 testPartResult.summary(), 60 testPartResult.file_name(), 61 testPartResult.line_number() 62 ); 63 } 64 } 65 66 // Called after a test ends. 67 virtual void OnTestEnd( const ::testing::TestInfo& testInfo ) 68 { 69 if( mVerbose ) 70 Con::printf("> Ending Test '%s.%s'\n", 71 testInfo.test_case_name(), testInfo.name()); 72 } 73 74 bool mVerbose; 75 76public: 77 TorqueUnitTestListener( bool verbose ) : mVerbose( verbose ) {} 78}; 79 80DefineEngineFunction( runAllUnitTests, int, (const char* testSpecs), (""), 81 "Runs engine unit tests. Some tests are marked as 'stress' tests which do not " 82 "necessarily check correctness, just performance or possible nondeterministic " 83 "glitches. There may also be interactive or networking tests which may be " 84 "excluded by using the testSpecs argument.\n" 85 "This function should only be called once per executable run, because of " 86 "googletest's design.\n\n" 87 88 "@param testSpecs A space-sepatated list of filters for test cases. " 89 "See https://code.google.com/p/googletest/wiki/AdvancedGuide#Running_a_Subset_of_the_Tests " 90 "and http://stackoverflow.com/a/14021997/945863 " 91 "for a description of the flag format.") 92{ 93 S32 testArgc = 0; 94 char** testArgv = NULL; 95 if ( dStrlen( testSpecs ) > 0 ) 96 { 97 String specs(testSpecs); 98 specs.replace(' ', ':'); 99 specs.insert(0, "--gtest_filter="); 100 testArgc = 2; 101 testArgv = new char*[2]; 102 testArgv[0] = NULL; // Program name is unused by googletest. 103 testArgv[1] = new char[specs.size()]; 104 dStrcpy(testArgv[1], specs, specs.size()); 105 } 106 107 // Initialize Google Test. 108 testing::InitGoogleTest( &testArgc, testArgv ); 109 110 // Fetch the unit test instance. 111 testing::UnitTest& unitTest = *testing::UnitTest::GetInstance(); 112 113 // Fetch the unit test event listeners. 114 testing::TestEventListeners& listeners = unitTest.listeners(); 115 116 // Release the default listener. 117 delete listeners.Release( listeners.default_result_printer() ); 118 119 if ( Con::getBoolVariable( "$Testing::CheckMemoryLeaks", false ) ) { 120 // Add the memory leak tester. 121 listeners.Append( new testing::MemoryLeakDetector ); 122 } 123 124 // Add the Torque unit test listener. 125 listeners.Append( new TorqueUnitTestListener(false) ); 126 127 // Perform googletest run. 128 Con::printf( "\nUnit Tests Starting...\n" ); 129 const S32 result = RUN_ALL_TESTS(); 130 Con::printf( "... Unit Tests Ended.\n" ); 131 132 return result; 133} 134 135#endif // TORQUE_TESTS_ENABLED 136