/** * \brief Initializes object * Resets counters and clears all stored test results. */ virtual void init() { ok_count = 0; exceptions_count = 0; failures_count = 0; terminations_count = 0; warnings_count = 0; all_tests.clear(); }
/** * \brief Callback function * This function is called before the first test is executed. It initializes counters. */ virtual void run_started() { ok_count = 0; exceptions_count = 0; failures_count = 0; terminations_count = 0; warnings_count = 0; all_tests_.clear(); }
/** * \brief Callback function * This function is called when all tests are completed. It generates XML output * to file(s). File name base can be set with constructor. */ virtual void run_completed() { /* *********************** header ***************************** */ *stream_ << "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>" << std::endl; *stream_ << "<testsuites>" << std::endl; // iterate over all test groups for (TestGroups::const_iterator tgi = all_tests_.begin(); tgi != all_tests_.end(); ++tgi) { /* per-group statistics */ int passed = 0; // passed in single group int exceptions = 0; // exceptions in single group int failures = 0; // failures in single group int terminations = 0; // terminations in single group int warnings = 0; // warnings in single group int errors = 0; // errors in single group // output is written to string stream buffer, because JUnit format <testsuite> tag // contains statistics, which aren't known yet std::ostringstream out; // iterate over all test cases in the current test group const TestResults &results = tgi->second; for (TestResults::const_iterator tri = results.begin(); tri != results.end(); ++tri) { std::string failure_type; // string describing the failure type std::string failure_msg; // a string with failure message switch (tri->result) { case test_result::ok: case test_result::skipped: passed++; break; case test_result::fail: failure_type = "Assertion"; failure_msg = ""; failures++; break; case test_result::ex: failure_type = "Assertion"; failure_msg = "Thrown exception: " + tri->exception_typeid + '\n'; exceptions++; break; case test_result::warn: failure_type = "Assertion"; failure_msg = "Destructor failed.\n"; warnings++; break; case test_result::term: failure_type = "Error"; failure_msg = "Test application terminated abnormally.\n"; terminations++; break; case test_result::ex_ctor: failure_type = "Assertion"; failure_msg = "Constructor has thrown an exception: " + tri->exception_typeid + ".\n"; exceptions++; break; case test_result::rethrown: failure_type = "Assertion"; failure_msg = "Child failed.\n"; failures++; break; default: failure_type = "Error"; failure_msg = "Unknown test status, this should have never happened. " "You may just have found a bug in TUT, please report it immediately.\n"; errors++; break; } // switch #if defined(TUT_USE_POSIX) out << xml_build_testcase(*tri, failure_type, failure_msg, tri->pid) << std::endl; #else out << xml_build_testcase(*tri, failure_type, failure_msg) << std::endl; #endif } // iterate over all test cases // calculate per-group statistics int stat_errors = terminations + errors; int stat_failures = failures + warnings + exceptions; int stat_all = stat_errors + stat_failures + passed; *stream_ << xml_build_testsuite(stat_errors, stat_failures, stat_all, (*tgi).first/* name */, out.str()/* testcases */) << std::endl; } // iterate over all test groups *stream_ << "</testsuites>" << std::endl; }
/** * \brief Callback function * This function is called when all tests are completed. It generates XML output * to file(s). File name base can be set with \ref setFilenameBase. */ virtual void run_completed() { using std::endl; using std::string; static int number = 1; // results file sequence number (testResult_<number>.xml) // iterate over all test groups TestGroups::const_iterator tgi; for (tgi = all_tests.begin(); tgi != all_tests.end(); ++tgi) { /* per-group statistics */ int passed = 0; // passed in single group int exceptions = 0; // exceptions in single group int failures = 0; // failures in single group int terminations = 0; // terminations in single group int warnings = 0; // warnings in single group int errors = 0; // errors in single group /* generate output filename */ char fn[256]; sprintf(fn, "%s_%d.xml", filename.c_str(), number++); std::ofstream xmlfile; xmlfile.open(fn, std::ios::in | std::ios::trunc); if (!xmlfile.is_open()) { throw (std::runtime_error("Cannot open file for output")); } /* *********************** header ***************************** */ xmlfile << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << endl; // output is written to string stream buffer, because JUnit format <testsuite> tag // contains statistics, which aren't known yet std::ostringstream out; // iterate over all test cases in the current test group TestResults::const_iterator tri; for (tri = (*tgi).second.begin(); tri != (*tgi).second.end(); ++tri) { string failure_type; // string describing the failure type string failure_msg; // a string with failure message switch ((*tri).result) { case test_result::ok: passed++; break; case test_result::fail: failure_type = "Assertion"; failure_msg = ""; failures++; break; case test_result::ex: failure_type = "Assertion"; failure_msg = "Thrown exception: " + (*tri).exception_typeid + '\n'; exceptions++; break; case test_result::warn: failure_type = "Assertion"; failure_msg = "Destructor failed.\n"; warnings++; break; case test_result::term: failure_type = "Error"; failure_msg = "Test application terminated abnormally.\n"; terminations++; break; case test_result::ex_ctor: failure_type = "Assertion"; failure_msg = "Constructor has thrown an exception: " + (*tri).exception_typeid + '\n'; exceptions++; break; case test_result::rethrown: failure_type = "Assertion"; failure_msg = "Child failed"; failures++; break; default: failure_type = "Error"; failure_msg = "Unknown test status, this should have never happened. " "You may just have found a BUG in TUT XML reporter, please report it immediately.\n"; errors++; break; } // switch #if defined(TUT_USE_POSIX) out << xml_build_testcase(*tri, failure_type, failure_msg, (*tri).pid) << endl; #else out << xml_build_testcase(*tri, failure_type, failure_msg) << endl; #endif } // iterate over all test cases // calculate per-group statistics int stat_errors = terminations + errors; int stat_failures = failures + warnings + exceptions; int stat_all = stat_errors + stat_failures + passed; xmlfile << xml_build_testsuite(stat_errors, stat_failures, stat_all, (*tgi).first/* name */, out.str()/* testcases */) << endl; xmlfile.close(); } // iterate over all test groups }