C++: Adding the first unit test
There is a number of test frameworks for C++.
When you want to add a test to your code, the question immediately follows: which testing framework do I use?
The answer is: whichever test framework you pick, it's much better to have one test run by a suboptimal test framework, than to have no tests until we pick the "perfect" test framework.
DocTest is a great framework to start with.
It has most features you will need, is simple to install and run.
To install DocTest, you download its header file doctest.h
from GitHub:
$ wget -c https://github.com/doctest/doctest/releases/latest/download/doctest.h
Next, place the file inside your project and create a .cpp
file with your first test.
Let's say we want to test a factorial function implemented in another header file.
The code we would add, naming its file test_factorial.cpp
:
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include "doctest.h"
#include "factorial.h"
TEST_CASE("testing the factorial function") {
CHECK(fact(0) == 1);
CHECK(fact(1) == 1);
CHECK(fact(2) == 2);
CHECK(fact(3) == 6);
CHECK(fact(10) == 3628800);
}
If your project is simple, you can add a shebang line that will let you compile and run the test in one command. Taking clang as the compiler example, the line would be:
//usr/bin/clang++ -std=c++11 -o ${0%.*} "$0" && ./${0%.*}; exit
Make the test file executable: chmod +x test_factorial.cpp
.
Now you can run your tests with one command:
$ ./test_factorial.cpp
[doctest] doctest version is "2.4.10"
[doctest] run with "--help" for options
===============================================================================
[doctest] test cases: 1 | 1 passed | 0 failed | 0 skipped
[doctest] assertions: 5 | 5 passed | 0 failed |
[doctest] Status: SUCCESS!
It does not matter, which test framework you use. What's important is that your code now has a unit test.
If you ever find you need a feature not provided by your current framework, you can always consider moving the tests to another, and meanwhile, the tests will already be serving you from now on by eliminating your fear of change.
No fear of change means fearless refactors.
Fearless refactors mean frequent refactors.
Frequent refactors that don't break the functionality mean clean code!