I have a BOOST_AUTO_TEST_CASE
which needs a helper function. I could just make this a regular function and call it from within; but I'd rather somehow keep it local and private to the scope of the BOOST_AUTO_CASE
. I'd also like to be able to declare vars which are in the scope of both the test case and the helper functions (e.g. const int serverCount = 10;
).
If the test case was a class (and not a macro), I'd simply use a private member function. How do I do this (or the equivalent) for a Boost unit test case?
Unit Tests Should Only Test Public Methods The short answer is that you shouldn't test private methods directly, but only their effects on the public methods that call them. Unit tests are clients of the object under test, much like the other classes in the code that are dependent on the object.
A unit test should test the public contract, the only way how a class could be used in other parts of the code. A private method is implementation details, you should not test it; as far as public API works correctly, the implementation doesn't matter and could be changed without changes in test cases.
Yes it is very bad practice - you're letting your tools make design decisions for you. I think the main problem here is that you're trying to treat each individual method as a unit. This is generally the cause of all unit test woes.
Luckily there is a solution for this right in the Boost test framework: Fixtures. There are different types of fixtures but in your case the per test case fixture seems to fit.
#define BOOST_TEST_MODULE example
#include <boost/test/included/unit_test.hpp>
struct TestContext {
TestContext() : testVar( 0 ) { BOOST_TEST_MESSAGE( "setup fixture" ); }
~TestContext() { BOOST_TEST_MESSAGE( "teardown fixture" ); }
int testVar;
void helperMethod(int x, double y)
{
testVar = x * (int)y;
}
};
BOOST_FIXTURE_TEST_CASE( test_case1, TestContext )
{
BOOST_CHECK( testVar == 1 );
++testVar;
}
BOOST_FIXTURE_TEST_CASE( test_case2, TestContext )
{
helperMethod(2, 3.1);
// ...
}
testVar
is accessible in the test case as well as in the TestContext
class / struct. TestContext
's constructor and destructor are called right before and after each test case respectively. They are not needed but can come in handy if you have to manage memory for example. In particular each test case is run with its own fresh instance of TestContext
.
Update: Still valid for Boost 1.66, link updated.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With