Writing Tests
How to Write Them
Test cases should take the format shown below. Make sure to give each test a unique name that describes what it tests.
TEST_CASE( "UniqueName" ) {
//Do any setup we need to
CHECK( something is true );
//CHECK will not stop this TEST_CASE if it fails
REQUIRE( something else is true );
//REQUIRE will stop this TEST_CASE if it fails
//Use it if following tests make no sense when this one fails
}
The Approx
macro is a part of the doctest.h framework and can be used to safely compare doubles.
(Recall that doubles are only guaranteed to be approximately correct - they will have a value
that is correct to ~15 significant digits).
Any time you want to test a double (or float) for a value, you should use Approx
to do so.
The general format is your_double == Approx(desired_answer)
. Something like:
TEST_CASE( "CheckDouble" ) {
double myAnswer = 3 + .01 + .01;
CHECK( myAnswer == Approx(3.02) );
//or
double desiredAnswer = 3.02;
CHECK( myAnswer == Approx(desiredAnswer) );
}
Approx
is part of the unit testing framework. It is NOT a standard part of C++. Never use
it in code outside of TEST_CASE
s.What to Test
Some general rules of testing:
- Each function should get tested.
- Exception: In objects, we might not write tests for trivial get/set function that are used in all the other tests.
- Each test should focus on testing one function. (Though you may have to use other functions as part of doing that.)
- A function will often need more than one test to check how it handles different situations. You
can handle this by either:
- Writing multiple
TEST_CASE
s that each have oneCHECK
orREQUIRE
. - Write one
TEST_CASE
with multipleCHECK
s and/orREQUIRE
s.
- Writing multiple
- Things to focus on:
- Does the function have conditional logic? If so, do you test each situation and the boundaries between them?
- Does the function loop? Do you check for edge cases (properly handling the start and end of a range)?