As you might already know, we use boost::test
. This serves as an entry point to our current organization. For more detailed information, see the documentation of the boost testing framework.
All tests are in the tests
folder, which might come as a suprise to you. After compiling, there should be few test executables of the form unitTest_…
in <build_dir>/tests/
.
Running unit tests
(current working directory is your build directory)
- To run all unit tests simply execute:
make test
or ctest
- To run a single unit test module:
2 ./unitTests_<module name>
- To run a specific test suit of a module:
2 ./unitTests_<module name> --run_test=<test suit name>
Adding a unit test module
Every unit test module (folder) contains a …_test_module.cpp
. It only describes the test and its name. Then you can add a subfolder for each class to test and place the tests in there. For example, if you want to add a test for the Geodata
class, you do that in tests/general/geodata-test/geodata_functional_test.cpp
.
boost::unit_test
Ok, now to the test itself. Boost uses a suite tree to organize tests. The top level is the master suite. If you don't specify another suite, your tests will be registered here. With BOOST_AUTO_TEST_SUITE
, you can open your own suite (internally, it's just another namespace). Then use BOOST_AUTO_TEST_CASE
to start and stop your test. Here's a simple Point test:
#include <boost/test/unit_test.hpp>
BOOST_AUTO_TEST_SUITE(simple_point_test)
BOOST_AUTO_TEST_CASE( point_test )
{
BOOST_CHECK_EQUAL( Point(3,3), Point(3,3));
BOOST_CHECK_EQUAL( Point(4,3), Point(3,3));
BOOST_CHECK_EQUAL( Point(5,3), Point(3,3));
}
BOOST_AUTO_TEST_SUITE_END()
Output:
2 /home/tobi/c++/alacarte/tests/utils/point-test/simple_point_test.cpp(10): error in "point_test": check Point(4,3) == Point(3,3) failed [4, 3 != 3, 3]
3 /home/tobi/c++/alacarte/tests/utils/point-test/simple_point_test.cpp(11): error in "point_test": check Point(5,3) == Point(3,3) failed [5, 3 != 3, 3]
5 *** 2 failures detected in test suite "utils test"
Test Cases with Parameters
If you want to test your own test function with different parameters, we built a little macro to help with that:
#include "../../tests.hpp"
BOOST_AUTO_TEST_SUITE(simple_point_test)
void equal_test(const Point& p1, const Point& p2)
{
BOOST_CHECK_EQUAL( p1, p2);
}
ALAC_PARAM_TEST_CASE(equal_test, Point(3, 4), Point(3, 4));
ALAC_PARAM_TEST_CASE(equal_test, Point(3, 8), Point(3, 4));
ALAC_PARAM_TEST_CASE(equal_test, Point(3, 4), Point(3, 8));
BOOST_AUTO_TEST_SUITE_END()
Output:
1 Running 3 test cases...
2 /home/tobi/c++/alacarte/tests/utils/point-test/simple_point_test.cpp(9): error in "equal_test_in_13": check p1 == p2 failed [3, 8 != 3, 4]
3 /home/tobi/c++/alacarte/tests/utils/point-test/simple_point_test.cpp(9): error in "equal_test_in_14": check p1 == p2 failed [3, 4 != 3, 8]
5 *** 2 failures detected in test suite "utils test"
Test Cases with Context
Sometimes you want to prepare a test, then execute the test and (sometimes 😉) clean up.
#include "../../tests.hpp"
BOOST_AUTO_TEST_SUITE(simple_point_test)
struct simple_check_test
{
simple_check_test(const Point& p)
{
point = p;
}
~simple_check_test()
{
}
void compare(const Point& p)
{
BOOST_CHECK_EQUAL(point, p);
}
Point point;
};
ALAC_START_FIXTURE_TEST(simple_check_test, Point(5, 5))
ALAC_FIXTURE_TEST(compare, Point(4,5));
ALAC_FIXTURE_TEST(compare, Point(4,6));
ALAC_FIXTURE_TEST_NAMED(compare, compare_4_and_7, Point(4,7));
ALAC_END_FIXTURE_TEST()
BOOST_AUTO_TEST_SUITE_END()
Output:
1 Running 3 test cases...
2 /home/tobi/c++/alacarte/tests/utils/point-test/simple_point_test.cpp(27): error in "compare_in_34": check point == p failed [5, 5 != 4, 5]
3 /home/tobi/c++/alacarte/tests/utils/point-test/simple_point_test.cpp(27): error in "compare_in_35": check point == p failed [5, 5 != 4, 6]
4 /home/tobi/c++/alacarte/tests/utils/point-test/simple_point_test.cpp(27): error in "compare_4_and_7": check point == p failed [5, 5 != 4, 7]
6 *** 3 failures detected in test suite "utils test"