Self-discoverable C++ tests without using macros. This CMake module lets you write test drivers like:
test1.cpp:
#include <assertion_macro.h>
void testAdditionIsGreat() {
ASSERT_EQ(1 + 1, 2);
}
void testMultiplicationIsCool() {
ASSERT_EQ(3 * 7, 21);
}
int helperFunction(int x) {
return x+1;
}
void testHelperFunctionIsBroken() {
ASSERT(helperFunction(3) != 4);
}Then you can link it (and possibly others) into a test executable:
add_executable(mytest
tests/test1.cpp
tests/test2.cpp
)
configure_cool_tests(mytest)and get the following output when running ctest:
AdditionIsGreat RUNNING
AdditionIsGreat SUCCESS
MultiplicationIsCool RUNNING
MultiplicationIsCool SUCCESS
HelperFunctionIsBroken RUNNING
HelperFunctionIsBroken FAILURE
ImplicitStringViewConversion RUNNING
ImplicitStringViewConversion SUCCESS
Tests passed 3/4
note that neither test1.cpp nor test2.cpp provide a main function.
Neither is one required to register the test functions anywhere. The
configure_cool_tests function will find all the function names that begin
with test and create a main function that invokes them.
Requirements:
- python3.8
- cmake
- A modern-enough C++ compiler (I use
std::span) - nm
Build this project:
$ cmake -S . -B build -Dcooltests_OwnTests=1
$ cd build
$ make -j
$ ctest -V
You shouldn't. But you can include it as a git submodule and add_subdirectory it.
Then you should be able to use configure_cool_tests.
Tests signal their failure by throwing. Pretty bad, but simple.
There are many things that are broken:
-
The object file generated by
cooltests.pymight be ABI-incompatible with the rest of your code. -
Test symbol detection is very broken. Anything that, once demangled by nm, begins with
testand ends with()will be considered as a test function in the global namespace. -
The
cooltests.pyprogram probably makes assumptions aboutnm's output that are too strict. -
...