1 #ifndef RADARELAB_UTILS_TESTS_H
2 #define RADARELAB_UTILS_TESTS_H
73 std::string local_info;
76 : file(file), line(line), call(call)
81 : file(file), line(line), call(call), local_info(local_info.str())
85 std::string format()
const;
87 void format(std::ostream& out)
const;
90 struct TestStack :
public std::vector<TestStackFrame>
95 std::string backtrace()
const;
98 void backtrace(std::ostream& out)
const;
112 template<
typename ...Args>
113 TestFailed(
const std::exception& e, Args&&... args)
116 add_stack_info(std::forward<Args>(args)...);
119 TestFailed(
const std::string& message) : message(message) {}
121 template<
typename ...Args>
122 TestFailed(
const std::string& message, Args&&... args)
125 add_stack_info(std::forward<Args>(args)...);
128 const char* what()
const noexcept
override {
return message.c_str(); }
130 template<
typename ...Args>
131 void add_stack_info(Args&&... args) { stack.emplace_back(std::forward<Args>(args)...); }
145 #define RADARELAB_UTILS_TEST_INFO(name) \
146 radarelab::utils::tests::LocationInfo radarelab_utils_test_location_info; \
147 radarelab::utils::tests::LocationInfo& name = radarelab_utils_test_location_info
152 void assert_true(
const A& actual)
155 std::stringstream ss;
156 ss <<
"actual value " << actual <<
" is not true";
160 void assert_true(std::nullptr_t actual);
164 void assert_false(
const A& actual)
167 std::stringstream ss;
168 ss <<
"actual value " << actual <<
" is not false";
169 throw TestFailed(ss.str());
172 void assert_false(std::nullptr_t actual);
178 template<
typename A,
typename E>
179 void assert_equal(
const A& actual,
const E& expected)
181 if (actual == expected)
return;
182 std::stringstream ss;
183 ss <<
"value '" << actual <<
"' is different than the expected '" << expected <<
"'";
184 throw TestFailed(ss.str());
191 template<
typename A,
typename E>
192 void assert_not_equal(
const A& actual,
const E& expected)
194 if (actual != expected)
return;
195 std::stringstream ss;
196 ss <<
"value '" << actual <<
"' is not different than the expected '" << expected <<
"'";
197 throw TestFailed(ss.str());
201 template<
typename A,
typename E>
202 void assert_less(
const A& actual,
const E& expected)
204 if (actual < expected)
return;
205 std::stringstream ss;
206 ss <<
"value '" << actual <<
"' is not less than the expected '" << expected <<
"'";
207 throw TestFailed(ss.str());
211 template<
typename A,
typename E>
212 void assert_less_equal(
const A& actual,
const E& expected)
214 if (actual <= expected)
return;
215 std::stringstream ss;
216 ss <<
"value '" << actual <<
"' is not less than or equals to the expected '" << expected <<
"'";
217 throw TestFailed(ss.str());
221 template<
typename A,
typename E>
222 void assert_greater(
const A& actual,
const E& expected)
224 if (actual > expected)
return;
225 std::stringstream ss;
226 ss <<
"value '" << actual <<
"' is not greater than the expected '" << expected <<
"'";
227 throw TestFailed(ss.str());
231 template<
typename A,
typename E>
232 void assert_greater_equal(
const A& actual,
const E& expected)
234 if (actual >= expected)
return;
235 std::stringstream ss;
236 ss <<
"value '" << actual <<
"' is not greater than or equals to the expected '" << expected <<
"'";
237 throw TestFailed(ss.str());
241 void assert_startswith(
const std::string& actual,
const std::string& expected);
244 void assert_endswith(
const std::string& actual,
const std::string& expected);
247 void assert_contains(
const std::string& actual,
const std::string& expected);
250 void assert_not_contains(
const std::string& actual,
const std::string& expected);
258 void assert_re_matches(
const std::string& actual,
const std::string& expected);
266 void assert_not_re_matches(
const std::string& actual,
const std::string& expected);
273 Actual(
const A& actual) : _actual(actual) {}
276 void istrue()
const { assert_true(_actual); }
277 void isfalse()
const { assert_false(_actual); }
278 template<
typename E>
void operator==(
const E& expected)
const { assert_equal(_actual, expected); }
279 template<
typename E>
void operator!=(
const E& expected)
const { assert_not_equal(_actual, expected); }
280 template<
typename E>
void operator<(
const E& expected)
const {
return assert_less(_actual, expected); }
281 template<
typename E>
void operator<=(
const E& expected)
const {
return assert_less_equal(_actual, expected); }
282 template<
typename E>
void operator>(
const E& expected)
const {
return assert_greater(_actual, expected); }
283 template<
typename E>
void operator>=(
const E& expected)
const {
return assert_greater_equal(_actual, expected); }
289 ActualCString(
const char* s) : _actual(s) {}
291 void istrue()
const {
return assert_true(_actual); }
292 void isfalse()
const {
return assert_false(_actual); }
293 void operator==(
const char* expected)
const;
294 void operator==(
const std::string& expected)
const;
295 void operator!=(
const char* expected)
const;
296 void operator!=(
const std::string& expected)
const;
297 void operator<(
const std::string& expected)
const;
298 void operator<=(
const std::string& expected)
const;
299 void operator>(
const std::string& expected)
const;
300 void operator>=(
const std::string& expected)
const;
301 void startswith(
const std::string& expected)
const;
302 void endswith(
const std::string& expected)
const;
303 void contains(
const std::string& expected)
const;
304 void not_contains(
const std::string& expected)
const;
305 void matches(
const std::string& re)
const;
306 void not_matches(
const std::string& re)
const;
309 struct ActualStdString :
public Actual<std::string>
311 ActualStdString(
const std::string& s) : Actual<std::string>(s) {}
313 void startswith(
const std::string& expected)
const;
314 void endswith(
const std::string& expected)
const;
315 void contains(
const std::string& expected)
const;
316 void not_contains(
const std::string& expected)
const;
317 void matches(
const std::string& re)
const;
318 void not_matches(
const std::string& re)
const;
321 struct ActualDouble :
public Actual<double>
323 using Actual::Actual;
325 void almost_equal(
double expected,
unsigned places)
const;
326 void not_almost_equal(
double expected,
unsigned places)
const;
330 inline Actual<A> actual(
const A& actual) {
return Actual<A>(actual); }
331 inline ActualCString actual(
const char* actual) {
return ActualCString(actual); }
332 inline ActualCString actual(
char* actual) {
return ActualCString(actual); }
333 inline ActualStdString actual(
const std::string& actual) {
return ActualStdString(actual); }
334 inline ActualDouble actual(
double actual) {
return ActualDouble(actual); }
336 struct ActualFunction :
public Actual<std::function<void()>>
338 using Actual::Actual;
340 void throws(
const std::string& what_match)
const;
343 inline ActualFunction actual_function(std::function<
void()> actual) {
return ActualFunction(actual); }
345 struct ActualFile :
public Actual<std::string>
347 using Actual::Actual;
350 void not_exists()
const;
351 void startswith(
const std::string& data)
const;
354 inline ActualFile actual_file(
const std::string& pathname) {
return ActualFile(pathname); }
363 #define wassert(...) \
366 } catch (radarelab::utils::tests::TestFailed& e) { \
367 e.add_stack_info(__FILE__, __LINE__, #__VA_ARGS__, radarelab_utils_test_location_info); \
369 } catch (std::exception& e) { \
370 throw radarelab::utils::tests::TestFailed(e, __FILE__, __LINE__, #__VA_ARGS__, radarelab_utils_test_location_info); \
374 #define wassert_true(...) wassert(actual(__VA_ARGS__).istrue())
377 #define wassert_false(...) wassert(actual(__VA_ARGS__).isfalse())
386 #define wcallchecked(func) \
389 } catch (radarelab::utils::tests::TestFailed& e) { \
390 e.add_stack_info(__FILE__, __LINE__, #func, radarelab_utils_test_location_info); \
392 } catch (std::exception& e) { \
393 throw radarelab::utils::tests::TestFailed(e, __FILE__, __LINE__, #func, radarelab_utils_test_location_info); \
424 : test_case(test_case), test_method(test_method) {}
434 void set_exception(std::exception& e)
438 error_message =
"test threw an exception with an empty error message";
442 void set_unknown_exception()
447 void set_setup_exception(std::exception& e)
454 void set_teardown_exception(std::exception& e)
461 bool is_success()
const
486 void set_setup_failed()
488 fail_setup =
"test case setup method threw an unknown exception";
491 void set_setup_failed(std::exception& e)
493 fail_setup =
"test case setup method threw an exception: ";
497 void set_teardown_failed()
499 fail_teardown =
"test case teardown method threw an unknown exception";
502 void set_teardown_failed(std::exception& e)
504 fail_teardown =
"test case teardown method threw an exception: ";
508 void add_test_method(TestMethodResult&& e)
510 methods.emplace_back(std::move(e));
513 bool is_success()
const
524 struct TestCaseResult;
526 struct TestMethodResult;
582 bool test_method_should_run(
const std::string& fullname)
const;
741 template<
typename ...Args>
744 methods.emplace_back(name, test_function);
751 template<
typename ...Args>
754 methods.emplace_back(name, test_function);
777 void test_teardown() {}
780 template<
typename Fixture,
typename... Args>
781 static inline Fixture* fixture_factory(Args... args)
789 template<
typename FIXTURE>
793 typedef FIXTURE Fixture;
795 Fixture* fixture =
nullptr;
796 std::function<Fixture*()> make_fixture;
798 template<
typename... Args>
802 make_fixture = std::bind(fixture_factory<FIXTURE, Args...>, args...);
808 fixture = make_fixture();
821 if (fixture) fixture->test_setup();
826 if (fixture) fixture->test_teardown();
834 template<
typename ...Args>
844 template<
typename ...Args>
845 TestMethod&
add_method(
const std::string& name,
const std::string& doc, std::function<
void(FIXTURE&)> test_function)
855 std::function<void()> test_func;
859 virtual void add_tests() {}
Result of running a whole test case.
std::string blacklist
Any method matching this glob expression will not be run.
bool skipped
Set to true if this test case has been skipped.
bool test_case_begin(const TestCase &test_case, const TestCaseResult &test_case_result) override
Called before running a test case.
Test case collecting several test methods, and self-registering with the singleton instance of TestRe...
std::string test_case
Name of the test case.
std::string test_case
Name of the test case.
virtual TestMethodResult run_test(TestController &controller, TestMethod &method)
Run a test method.
void method_teardown(TestMethodResult &mr) override
Clean up after the test method is run.
std::string doc
Documentation attached to this test method.
void method_setup(TestMethodResult &mr) override
Set up before the test method is run.
Base class for test fixtures.
static TestRegistry & get()
Get the singleton instance of TestRegistry.
bool test_method_begin(const TestMethod &test_method, const TestMethodResult &test_method_result) override
Called before running a test method.
virtual TestCaseResult run_tests(TestController &controller)
Call setup(), run all the tests that have been registered, then call teardown().
Test case that includes a fixture.
std::vector< TestMethod > methods
All registered test methods.
virtual void register_tests()=0
This will be called before running the test case, to populate it with its test methods.
std::function< void()> test_function
Main body of the test method.
TestMethod & add_method(const std::string &name, const std::string &doc, std::function< void()> test_function)
Register a new test method, including documentation.
Exception thrown when a test or a test case needs to be skipped.
std::string name
Name of the test case.
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...
virtual void test_case_end(const TestCase &test_case, const TestCaseResult &test_case_result)
Called after running a test case.
Result of running a test method.
Abstract interface for the objects that supervise test execution.
std::string test_method
Name of the test method.
bool skipped
True if the test has been skipped.
void setup() override
Set up the test case before it is run.
virtual bool test_case_begin(const TestCase &test_case, const TestCaseResult &test_case_result)
Called before running a test case.
void register_tests_once()
Idempotent wrapper for register_tests()
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.
void register_test_case(TestCase &test_case)
Register a new test case.
void iterate_test_methods(std::function< void(const TestCase &, const TestMethod &)>)
Iterate on all test methods known by this registry.
Information about one stack frame in the test execution stack.
virtual bool test_method_begin(const TestMethod &test_method, const TestMethodResult &test_method_result)
Called before running a test method.
std::vector< TestMethodResult > methods
Outcome of all the methods that have been run.
Simple default implementation of TestController.
TestStack error_stack
Stack frame of where the error happened.
TestMethod & add_method(const std::string &name)
Register a new test method, with the actual test function to be added later.
Add information to the test backtrace for the tests run in the current scope.
void test_method_end(const TestMethod &test_method, const TestMethodResult &test_method_result) override
Called after running a test method.
std::string exception_typeid
If non-empty, the test threw an exception and this is its type ID.
void test_case_end(const TestCase &test_case, const TestCaseResult &test_case_result) override
Called after running a test case.
std::string whitelist
Any method not matching this glob expression will not be run.
void teardown() override
Clean up after the test case is run.
virtual void teardown()
Clean up after the test case is run.
std::ostream & operator()()
Clear the current information and return the output stream to which new information can be sent...
TestMethod & add_method(const std::string &name, std::function< void()> test_function)
Register a new test method.
std::string fail_teardown
Set to a non-empty string if the teardown method of the test case failed.
std::string error_message
If non-empty, the test failed with this error.
std::vector< TestCase * > entries
All known test cases.
std::string fail_setup
Set to a non-empty string if the setup method of the test case failed.
virtual void test_method_end(const TestMethod &test_method, const TestMethodResult &test_method_result)
Called after running a test method.
virtual void setup()
Set up the test case before it is run.
virtual void method_setup(TestMethodResult &)
Set up before the test method is run.
bool tests_registered
Set to true the first time register_tests_once is run.
virtual void method_teardown(TestMethodResult &)
Clean up after the test method is run.
std::string name
Name of the test method.
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.