1 #ifndef WREPORT_TESTS_H
2 #define WREPORT_TESTS_H
71 std::string local_info;
74 : file(file), line(line), call(call)
79 : file(file), line(line), call(call), local_info(local_info.str())
83 std::string format()
const;
85 void format(std::ostream& out)
const;
88 struct TestStack :
public std::vector<TestStackFrame>
110 template<
typename ...Args>
111 TestFailed(
const std::exception& e, Args&&... args)
114 add_stack_info(std::forward<Args>(args)...);
117 TestFailed(
const std::string& message) : message(message) {}
119 template<
typename ...Args>
120 TestFailed(
const std::string& message, Args&&... args)
123 add_stack_info(std::forward<Args>(args)...);
126 const char* what()
const noexcept
override {
return message.c_str(); }
128 template<
typename ...Args>
129 void add_stack_info(Args&&... args) { stack.emplace_back(std::forward<Args>(args)...); }
143 #define WREPORT_TEST_INFO(name) \
144 wreport::tests::LocationInfo wreport_test_location_info; \
145 wreport::tests::LocationInfo& name = wreport_test_location_info
157 void assert_true(
const A& actual)
160 std::stringstream ss;
161 ss <<
"actual value " << actual <<
" is not true";
165 void assert_true(std::nullptr_t actual);
169 void assert_false(
const A& actual)
172 std::stringstream ss;
173 ss <<
"actual value " << actual <<
" is not false";
174 throw TestFailed(ss.str());
177 void assert_false(std::nullptr_t actual);
183 template<
typename A,
typename E>
184 void assert_equal(
const A& actual,
const E& expected)
186 if (actual == expected)
return;
187 std::stringstream ss;
188 ss <<
"value '" << actual <<
"' is different than the expected '" << expected <<
"'";
189 throw TestFailed(ss.str());
196 template<
typename A,
typename E>
197 void assert_not_equal(
const A& actual,
const E& expected)
199 if (actual != expected)
return;
200 std::stringstream ss;
201 ss <<
"value '" << actual <<
"' is not different than the expected '" << expected <<
"'";
202 throw TestFailed(ss.str());
206 template<
typename A,
typename E>
207 void assert_less(
const A& actual,
const E& expected)
209 if (actual < expected)
return;
210 std::stringstream ss;
211 ss <<
"value '" << actual <<
"' is not less than the expected '" << expected <<
"'";
212 throw TestFailed(ss.str());
216 template<
typename A,
typename E>
217 void assert_less_equal(
const A& actual,
const E& expected)
219 if (actual <= expected)
return;
220 std::stringstream ss;
221 ss <<
"value '" << actual <<
"' is not less than or equals to the expected '" << expected <<
"'";
222 throw TestFailed(ss.str());
226 template<
typename A,
typename E>
227 void assert_greater(
const A& actual,
const E& expected)
229 if (actual > expected)
return;
230 std::stringstream ss;
231 ss <<
"value '" << actual <<
"' is not greater than the expected '" << expected <<
"'";
232 throw TestFailed(ss.str());
236 template<
typename A,
typename E>
237 void assert_greater_equal(
const A& actual,
const E& expected)
239 if (actual >= expected)
return;
240 std::stringstream ss;
241 ss <<
"value '" << actual <<
"' is not greater than or equals to the expected '" << expected <<
"'";
242 throw TestFailed(ss.str());
246 void assert_startswith(
const std::string& actual,
const std::string& expected);
249 void assert_endswith(
const std::string& actual,
const std::string& expected);
252 void assert_contains(
const std::string& actual,
const std::string& expected);
255 void assert_not_contains(
const std::string& actual,
const std::string& expected);
263 void assert_re_matches(
const std::string& actual,
const std::string& expected);
271 void assert_not_re_matches(
const std::string& actual,
const std::string& expected);
278 Actual(
const A& actual) : _actual(actual) {}
281 void istrue()
const { assert_true(_actual); }
282 void isfalse()
const { assert_false(_actual); }
283 template<
typename E>
void operator==(
const E& expected)
const { assert_equal(_actual, expected); }
284 template<
typename E>
void operator!=(
const E& expected)
const { assert_not_equal(_actual, expected); }
285 template<
typename E>
void operator<(
const E& expected)
const {
return assert_less(_actual, expected); }
286 template<
typename E>
void operator<=(
const E& expected)
const {
return assert_less_equal(_actual, expected); }
287 template<
typename E>
void operator>(
const E& expected)
const {
return assert_greater(_actual, expected); }
288 template<
typename E>
void operator>=(
const E& expected)
const {
return assert_greater_equal(_actual, expected); }
296 void istrue()
const {
return assert_true(_actual); }
297 void isfalse()
const {
return assert_false(_actual); }
298 void operator==(
const char* expected)
const;
299 void operator==(
const std::string& expected)
const;
300 void operator!=(
const char* expected)
const;
301 void operator!=(
const std::string& expected)
const;
302 void operator<(
const std::string& expected)
const;
303 void operator<=(
const std::string& expected)
const;
304 void operator>(
const std::string& expected)
const;
305 void operator>=(
const std::string& expected)
const;
306 void startswith(
const std::string& expected)
const;
307 void endswith(
const std::string& expected)
const;
308 void contains(
const std::string& expected)
const;
309 void not_contains(
const std::string& expected)
const;
310 void matches(
const std::string& re)
const;
311 void not_matches(
const std::string& re)
const;
318 void startswith(
const std::string& expected)
const;
319 void endswith(
const std::string& expected)
const;
320 void contains(
const std::string& expected)
const;
321 void not_contains(
const std::string& expected)
const;
322 void matches(
const std::string& re)
const;
323 void not_matches(
const std::string& re)
const;
328 using Actual::Actual;
330 void almost_equal(
double expected,
unsigned places)
const;
331 void not_almost_equal(
double expected,
unsigned places)
const;
336 inline ActualCString actual(
const char* actual) {
return ActualCString(actual); }
337 inline ActualCString actual(
char* actual) {
return ActualCString(actual); }
338 inline ActualStdString actual(
const std::string& actual) {
return ActualStdString(actual); }
339 inline ActualDouble actual(
double actual) {
return ActualDouble(actual); }
343 using Actual::Actual;
345 void throws(
const std::string& what_match)
const;
352 using Actual::Actual;
355 void not_exists()
const;
356 void startswith(
const std::string& data)
const;
368 #define wassert(...) \
371 } catch (wreport::tests::TestFailed& e) { \
372 e.add_stack_info(__FILE__, __LINE__, #__VA_ARGS__, wreport_test_location_info); \
374 } catch (std::exception& e) { \
375 throw wreport::tests::TestFailed(e, __FILE__, __LINE__, #__VA_ARGS__, wreport_test_location_info); \
379 #define wassert_true(...) wassert(actual(__VA_ARGS__).istrue())
382 #define wassert_false(...) wassert(actual(__VA_ARGS__).isfalse())
389 #define wassert_throws(exc, ...) \
392 wfail_test(#__VA_ARGS__ " did not throw " #exc); \
395 } catch (std::exception& e) { \
396 std::string msg(#__VA_ARGS__ " did not throw " #exc " but threw "); \
397 msg += typeid(e).name(); \
409 #define wcallchecked(func) \
412 } catch (wreport::tests::TestFailed& e) { \
413 e.add_stack_info(__FILE__, __LINE__, #func, wreport_test_location_info); \
415 } catch (std::exception& e) { \
416 throw wreport::tests::TestFailed(e, __FILE__, __LINE__, #func, wreport_test_location_info); \
422 #define wfail_test(msg) wassert(throw wreport::tests::TestFailed((msg)))
451 : test_case(test_case), test_method(test_method) {}
461 void set_exception(std::exception& e)
465 error_message =
"test threw an exception with an empty error message";
469 void set_unknown_exception()
474 void set_setup_exception(std::exception& e)
481 void set_teardown_exception(std::exception& e)
488 bool is_success()
const
513 void set_setup_failed()
515 fail_setup =
"test case setup method threw an unknown exception";
518 void set_setup_failed(std::exception& e)
520 fail_setup =
"test case setup method threw an exception: ";
524 void set_teardown_failed()
526 fail_teardown =
"test case teardown method threw an unknown exception";
529 void set_teardown_failed(std::exception& e)
531 fail_teardown =
"test case teardown method threw an exception: ";
535 void add_test_method(TestMethodResult&& e)
537 methods.emplace_back(std::move(e));
540 bool is_success()
const
551 struct TestCaseResult;
553 struct TestMethodResult;
609 bool test_method_should_run(
const std::string& fullname)
const;
768 template<
typename ...Args>
771 methods.emplace_back(name, test_function);
778 template<
typename ...Args>
781 methods.emplace_back(name, test_function);
804 void test_teardown() {}
807 template<
typename Fixture,
typename... Args>
808 static inline Fixture* fixture_factory(Args... args)
816 template<
typename FIXTURE>
820 typedef FIXTURE Fixture;
822 Fixture* fixture =
nullptr;
823 std::function<Fixture*()> make_fixture;
825 template<
typename... Args>
829 make_fixture = std::bind(fixture_factory<FIXTURE, Args...>, args...);
835 fixture = make_fixture();
848 if (fixture) fixture->test_setup();
853 if (fixture) fixture->test_teardown();
861 template<
typename ...Args>
871 template<
typename ...Args>
872 TestMethod&
add_method(
const std::string& name,
const std::string& doc, std::function<
void(FIXTURE&)> test_function)
Test registry.
Definition: utils/tests.h:619
virtual void test_method_end(const TestMethod &test_method, const TestMethodResult &test_method_result)
Called after running a test method.
Definition: utils/tests.h:587
virtual TestCaseResult run_tests(TestController &controller)
Call setup(), run all the tests that have been registered, then call teardown().
std::string exception_typeid
If non-empty, the test threw an exception and this is its type ID.
Definition: utils/tests.h:444
void test_method_end(const TestMethod &test_method, const TestMethodResult &test_method_result) override
Called after running a test method.
Result of running a whole test case.
Definition: utils/tests.h:497
TestMethod & add_method(const std::string &name, std::function< void(FIXTURE &)> test_function)
Register a new test method that takes a reference to the fixture as argument.
Definition: utils/tests.h:862
Test case collecting several test methods, and self-registering with the singleton instance of TestRe...
Definition: utils/tests.h:679
std::string name
Name of the test case.
Definition: utils/tests.h:682
Information about one stack frame in the test execution stack.
Definition: utils/tests.h:66
Add information to the test backtrace for the tests run in the current scope.
Definition: utils/tests.h:54
std::string test_method
Name of the test method.
Definition: utils/tests.h:435
Exception thrown when a test or a test case needs to be skipped.
Definition: utils/tests.h:135
virtual bool test_method_begin(const TestMethod &test_method, const TestMethodResult &test_method_result)
Called before running a test method.
Definition: utils/tests.h:582
virtual void method_setup(TestMethodResult &)
Set up before the test method is run.
Definition: utils/tests.h:725
std::vector< TestMethodResult > methods
Outcome of all the methods that have been run.
Definition: utils/tests.h:502
void register_tests_once()
Idempotent wrapper for register_tests()
Simple default implementation of TestController.
Definition: utils/tests.h:596
TestStack error_stack
Stack frame of where the error happened.
Definition: utils/tests.h:441
bool tests_registered
Set to true the first time register_tests_once is run.
Definition: utils/tests.h:688
Abstract interface for the objects that supervise test execution.
Definition: utils/tests.h:561
std::string fail_teardown
Set to a non-empty string if the teardown method of the test case failed.
Definition: utils/tests.h:507
Definition: utils/tests.h:275
bool skipped
Set to true if this test case has been skipped.
Definition: utils/tests.h:509
virtual TestMethodResult run_test(TestController &controller, TestMethod &method)
Run a test method.
void teardown() override
Clean up after the test case is run.
Definition: utils/tests.h:838
std::vector< TestCaseResult > run_tests(TestController &controller)
Run all the registered tests using the given controller.
Exception thrown when a test assertion fails, normally by Location::fail_test.
Definition: utils/tests.h:103
TestMethod & add_method(const std::string &name)
Register a new test method, with the actual test function to be added later.
Definition: utils/tests.h:759
void method_teardown(TestMethodResult &mr) override
Clean up after the test method is run.
Definition: utils/tests.h:851
void register_test_case(TestCase &test_case)
Register a new test case.
std::string backtrace() const
Return the formatted backtrace for this location.
std::vector< TestMethod > methods
All registered test methods.
Definition: utils/tests.h:685
TestMethod & add_method(const std::string &name, const std::string &doc, std::function< void(FIXTURE &)> test_function)
Register a new test method that takes a reference to the fixture as argument, including documentation...
Definition: utils/tests.h:872
TestMethod & add_method(const std::string &name, std::function< void()> test_function)
Register a new test method.
Definition: utils/tests.h:769
Definition: utils/tests.h:88
static TestRegistry & get()
Get the singleton instance of TestRegistry.
virtual void setup()
Set up the test case before it is run.
Definition: utils/tests.h:715
std::vector< TestCase * > entries
All known test cases.
Definition: utils/tests.h:622
Definition: utils/tests.h:291
std::string doc
Documentation attached to this test method.
Definition: utils/tests.h:658
virtual void test_case_end(const TestCase &test_case, const TestCaseResult &test_case_result)
Called after running a test case.
Definition: utils/tests.h:575
std::string test_case
Name of the test case.
Definition: utils/tests.h:500
Definition: utils/tests.h:341
Definition: utils/tests.h:326
bool skipped
True if the test has been skipped.
Definition: utils/tests.h:447
std::string blacklist
Any method matching this glob expression will not be run.
Definition: utils/tests.h:602
Result of running a test method.
Definition: utils/tests.h:429
virtual bool test_case_begin(const TestCase &test_case, const TestCaseResult &test_case_result)
Called before running a test case.
Definition: utils/tests.h:570
void iterate_test_methods(std::function< void(const TestCase &, const TestMethod &)>)
Iterate on all test methods known by this registry.
Definition: utils/tests.h:350
void setup() override
Set up the test case before it is run.
Definition: utils/tests.h:832
std::function< void()> test_function
Main body of the test method.
Definition: utils/tests.h:665
void method_setup(TestMethodResult &mr) override
Set up before the test method is run.
Definition: utils/tests.h:845
Definition: utils/tests.h:314
std::string whitelist
Any method not matching this glob expression will not be run.
Definition: utils/tests.h:599
virtual void register_tests()=0
This will be called before running the test case, to populate it with its test methods.
std::string error_message
If non-empty, the test failed with this error.
Definition: utils/tests.h:438
Test case that includes a fixture.
Definition: utils/tests.h:817
Test method information.
Definition: utils/tests.h:652
virtual void method_teardown(TestMethodResult &)
Clean up after the test method is run.
Definition: utils/tests.h:730
virtual void teardown()
Clean up after the test case is run.
Definition: utils/tests.h:720
std::string name
Name of the test method.
Definition: utils/tests.h:655
Base class for test fixtures.
Definition: utils/tests.h:798
std::string fail_setup
Set to a non-empty string if the setup method of the test case failed.
Definition: utils/tests.h:504
std::string test_case
Name of the test case.
Definition: utils/tests.h:432
bool test_method_begin(const TestMethod &test_method, const TestMethodResult &test_method_result) override
Called before running a test method.
std::ostream & operator()()
Clear the current information and return the output stream to which new information can be sent...
bool test_case_begin(const TestCase &test_case, const TestCaseResult &test_case_result) override
Called before running a test case.
TestMethod & add_method(const std::string &name, const std::string &doc, std::function< void()> test_function)
Register a new test method, including documentation.
Definition: utils/tests.h:779
void test_case_end(const TestCase &test_case, const TestCaseResult &test_case_result) override
Called after running a test case.