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_CASEs.

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_CASEs that each have one CHECK or REQUIRE.
    • Write one TEST_CASE with multiple CHECKs and/or REQUIREs.
  • 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)?