In the previous instalment, Autotools were used to create a separate library from our source code. This time I will show how to add unit tests.

Unit testing is a very important tool for every software engineer and fortunately the Autotools provide us with an easy way to create and use unit tests. After creating the tests running them is as easy as running the following command on the command line:

make check

I will continue where I left of with the Autotools setup for libraries to show how to incorporate unit tests in your project based on the CppUnit. Why not one of the more recent C++ unit test environments such as the Boost Test Library or CxxTest? Simply because I am more experienced using CppUnit and know how to set up Autotools with it. In later instalments I will add setups for other testing frameworks but these setups will probably deviate not too much from the setup using CppUnit.

It is of course assumed that the CppUnit test framework is already installed on your machine. If not then the internet provides sufficient information on how to do so.

Necessary files and directories

Tests reside in their own directory, namely ‘test’ in your project root directory. This section will create the necessary structure and files.

Create the ‘test’-directory

From the project root directory issue the following command:

mkdir test

Create test/test_create_hello.h

In the newly created ‘test’-directory add a file ‘test_create_hello.h’ with the following contents:

#ifndef TEST_CREATE_HELLO_H
#define TEST_CREATE_HELLO_H
 
#include <cppunit/extensions/HelperMacros.h>
 
class CreateHelloTest : public CppUnit::TestFixture
{
  CPPUNIT_TEST_SUITE(CreateHelloTest);
  CPPUNIT_TEST(testHelloWorldCreation);
  CPPUNIT_TEST_SUITE_END();
 
public:
 
  void setUp() { }
  void tearDown() { }
 
protected:
 
  void testHelloWorldCreation();
 
}; // class CreateHelloTest
 
#endif // TEST_CREATE_HELLO_H

Create test/create_hello.cpp

Of course an implementation is needed. Add the file ‘test_create_hello.cpp’ with the following contents in the ‘test’-directory:

#include "test_create_hello.h"
 
#include "create_hello.h"
 
CPPUNIT_TEST_SUITE_REGISTRATION(CreateHelloTest);
 
void CreateHelloTest::testHelloWorldCreation()
{
  CPPUNIT_ASSERT(create_hello("World") == "Hello, World!");
}

Create test/Makefile.am

As with the library and the application we need to add a ‘Makefile.am’ from which the final ‘Makefile’ will be created:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# NH: Define the available tests
TESTS = CreateHelloTest
 
# NH: Define the tests that will run on 'make check'.
check_PROGRAMS = $(TESTS)
.
# NH: Define the source files for the test, other tests would get their own definition.
CreateHelloTest_SOURCES = main.cpp test_create_hello.cpp test_create_hello.h
 
# NH: Tell the preprocessor where the header files can be found.
AM_CPPFLAGS  = -I$(top_srcdir)/lib
 
# NH: Set the compile flags for all tests.
AM_CXXFLAGS  = -Wall -Werror -Weffc++ -Wextra -pedantic -std=c++11 $(CPPUNIT_CFLAGS)
 
# NH: Link the tests against the library under test
LDADD = ../lib/libfoobar.la
 
# Add the linker flags for the CppUnit library
AM_LDFLAGS = $(CPPUNIT_LIBS)
 
MAINTAINERCLEANFILES = Makefile.in

Change existing files

Several files need to be adjusted again to tell our environment that we have unit tests and a unit test framework.

Adjust configure.ac

Just below the ‘LT_INIT’ macro add the following:

dnl The following macro finds the CppUnit installation and sets variables that can be used
dnl later to find the CppUnit Headers and link our tests against the CppUnit library.
dnl It is assumed here that the CppUnit version >= 1.13.
AM_PATH_CPPUNIT([1.13])

The parameters to ‘AC_CONFIG_FILES’ should be extended with the location of the ‘Makefile’ in the ‘test’-directory:

AC_CONFIG_FILES([
    Makefile
    lib/Makefile
    src/Makefile
    test/Makefile])

Adjust Makefile.am

We need to let top top ‘Makefile.am’ know that another ‘Makefile.am’ can be found in the ‘test’-directory so the ‘SUBDIRS’ variable should include ‘tests:

6
SUBDIRS = lib src test

Rebuild and test the current setup

Reconfigure the environment and make sure a new ‘configure’ script is created:

autoreconf -ivf

Now you are able to build and run the tests. Just by running ‘make check’ as shown below, all necessary code will be build and run:
The following steps will define the default link behaviour, which is most likely to use the dynamic link-library:

./configure && make check

This finishes this third instalment showing how to incorporate unit tests based on CppUnit. Next we will take a look at creating Doxygen documentation.