diff options
author | Bent Bisballe Nyeng <bbn@mjolner.dk> | 2020-10-26 15:33:28 +0100 |
---|---|---|
committer | Bent Bisballe Nyeng <bbn@mjolner.dk> | 2020-10-26 15:33:28 +0100 |
commit | 1bd908531600b1392d98f2e3bfa21e3227df670b (patch) | |
tree | 8f3200c54ddfad8778b28b13ea3dc064a5f941c3 | |
parent | 128ba328ae7ff645cdec616d5519f5cf0a278079 (diff) |
Add exception catching to make sure, a test that results in an exception being thrown, will result in a test case failure.
-rw-r--r-- | uunit.h | 58 |
1 files changed, 46 insertions, 12 deletions
@@ -13,6 +13,7 @@ #include <sstream> #include <fstream> #include <cmath> +#include <exception> class uUnit { @@ -47,6 +48,7 @@ public: std::string file; std::size_t line; std::string msg; + std::string failure_type; int id; }; @@ -70,7 +72,7 @@ public: try { suite->setup(); - test.first(); + test.func(); suite->teardown(); } catch(test_result& result) @@ -78,18 +80,41 @@ public: std::cout << "F"; fflush(stdout); result.id = test_num; - result.func = test.second; + result.func = test.name; + result.failure_type = "Assertion"; failed_tests.push_back(result); ++failed; continue; } catch(...) { - break; // Uncaught exception. Do not proceed with this test. + test_result result; + std::cout << "F"; + fflush(stdout); + result.id = test_num; + result.func = test.name; + result.file = test.file; + result.line = 0; + try + { + throw; + } + catch(std::exception& e) + { + result.msg = std::string("Uncaught exception: ") + e.what(); + } + catch(...) + { + result.msg = "Uncaught exception without std::exception type"; + } + result.failure_type = "Exception"; + failed_tests.push_back(result); + ++failed; + continue; } std::cout << "."; fflush(stdout); - test_result result{test.second}; + test_result result{test.name}; result.id = test_num; successful_tests.push_back(result); } @@ -99,11 +124,12 @@ public: std::endl; out << "<TestRun>" << std::endl; out << " <FailedTests>" << std::endl; - for(auto test : failed_tests) + for(const auto& test : failed_tests) { - out << " <FailedTest id=\"" << test.id << "\">" << std::endl; + out << " <FailedTest id=\"" << test.id << "\">" << std::endl; // constexpr newline cross-platform specifik out << " <Name>" << sanitize(test.func) << "</Name>" << std::endl; - out << " <FailureType>Assertion</FailureType>" << std::endl; + out << " <FailureType>" << sanitize(test.failure_type) << + "</FailureType>" << std::endl; out << " <Location>" << std::endl; out << " <File>" << sanitize(test.file) << "</File>" << std::endl; out << " <Line>" << test.line << "</Line>" << std::endl; @@ -114,7 +140,7 @@ public: } out << " </FailedTests>" << std::endl; out << " <SuccessfulTests>" << std::endl; - for(auto test : successful_tests) + for(const auto& test : successful_tests) { out << " <Test id=\"" << test.id << "\">" << std::endl; out << " <Name>" << sanitize(test.func) << "</Name>" << std::endl; @@ -138,12 +164,12 @@ public: protected: template<typename O, typename F> - void registerTest(O* obj, const F& fn, const char* name) + void registerTest(O* obj, const F& fn, const char* name, const char* file) { - tests.emplace_back(std::make_pair(std::bind(fn, obj), name)); + tests.push_back({std::bind(fn, obj), name, file}); } #define uUNIT_TEST(func) \ - registerTest(this, &func, #func) + registerTest(this, &func, #func, __FILE__) void u_assert(bool value, const char* expr, const char* file, std::size_t line) @@ -219,7 +245,15 @@ private: static uUnit* suite_list; uUnit* next_unit{nullptr}; - std::vector<std::pair<std::function<void()>, const char*>> tests; + + struct test_t + { + std::function<void()> func; + const char* name; + const char* file; + }; + + std::vector<test_t> tests; }; #ifdef uUNIT_MAIN |