5.7. Unit Tests#

Unit tests are a way to check if your program runs as expected. Combine unit tests with makefiles, then you can automate both the compiling and testing phase of development. We call these tests unit tests because they are supposed to test a singular functionality of a component in a system rather than the whole system. You will spend less time debugging unit tests than testing the entire system because you can determine that the problem is with the specific functionality that it is testing.

Creating your own tests are essential to completing the programming assignments.

As an example, we have 3 functions: foo, bar, and baz. foo is a helper function to bar and baz, and bar is a helper function to baz.

int foo()
{
    ...
}

int bar()
{
    ...
    return foo();
}

int baz()
{
    ...
    return bar() * foo()
}

int main()
{
    assert(foo() > 0);  // this is a first level unit test
    assert(bar() > 0);  // this is a second level unit test
    assert(baz() > 0);  // this is a final level unit test aka system test
    return 0;
}

It would be very easy to create a test for baz and check the expected outputs, however, there is a possibility that the test passes for the wrong reasons (two wrongs might make a right). In the case that testing baz fails, it would be much harder to debug baz without first testing if both foo and bar pass their tests. Although this is a simple example, this idea of creating unit tests from the first level to the last will greatly improve development effeciency, and will train you to think about a complex system in bite sized chunks.