bool run_test(TestCase& testCase, bool catch_exceptions) { gCurrentTestCase = testCase; if (catch_exceptions) { try { gCurrentTestCase = testCase; testCase.execute(); // the test code may declare itself failed bool result = !gCurrentTestCase.failed; post_test_sanity_check(); return result; } catch (std::runtime_error const& err) { std::cout << "Error white running test case " << testCase.name << std::endl; std::cout << err.what() << std::endl; return false; } } else { testCase.execute(); } post_test_sanity_check(); return !gCurrentTestCase.failed; }
bool UnitTestDriver::run_tests(std::vector<UnitTest *>& tests_to_run, const ArgumentMap& kwargs) { std::time_t start_time = std::time(0); bool verbose = kwargs.count("verbose"); bool concise = kwargs.count("concise"); std::vector< TestResult > test_results; if (verbose && concise) { std::cout << "--verbose and --concise cannot be used together" << std::endl; exit(EXIT_FAILURE); } if (!concise) std::cout << "Running " << tests_to_run.size() << " unit tests." << std::endl; for(size_t i = 0; i < tests_to_run.size(); i++){ UnitTest& test = *tests_to_run[i]; if (verbose) std::cout << "Running " << test.name << "..." << std::flush; try { // time the test std::clock_t start = std::clock(); // run the test test.run(); // test passed record_result(TestResult(Pass, std::clock() - start, test), test_results); } catch (unittest::UnitTestFailure& f) { record_result(TestResult(Failure, std::numeric_limits<std::clock_t>::max(), test, f.message), test_results); } catch (unittest::UnitTestKnownFailure& f) { record_result(TestResult(KnownFailure, std::numeric_limits<std::clock_t>::max(), test, f.message), test_results); } catch (std::bad_alloc& e) { record_result(TestResult(Error, std::numeric_limits<std::clock_t>::max(), test, e.what()), test_results); } catch (unittest::UnitTestError& e) { record_result(TestResult(Error, std::numeric_limits<std::clock_t>::max(), test, e.message), test_results); } // immediate report if (!concise) { if (verbose) { switch(test_results.back().status) { case Pass: std::cout << "\r[PASS] "; std::cout << std::setw(10) << 1000.f * float(test_results.back().elapsed) / CLOCKS_PER_SEC << " ms"; break; case Failure: std::cout << "\r[FAILURE] "; break; case KnownFailure: std::cout << "\r[KNOWN FAILURE] "; break; case Error: std::cout << "\r[ERROR] "; break; default: break; } std::cout << " " << test.name << std::endl; } else { switch(test_results.back().status) { case Pass: std::cout << "."; break; case Failure: std::cout << "F"; break; case KnownFailure: std::cout << "K"; break; case Error: std::cout << "E"; break; default: break; } } } if (!post_test_sanity_check(test, concise)) { return false; } std::cout.flush(); } double elapsed_minutes = double(std::time(0) - start_time) / 60; // summary report if (!concise) report_results(test_results, elapsed_minutes); // if any failures or errors return false for(size_t i = 0; i < test_results.size(); i++) if (test_results[i].status != Pass && test_results[i].status != KnownFailure) return false; // all tests pass or are known failures return true; }