Crash Course in using CppUnit

Introduction

This document will introduce you to a testing framework called CppUnit. CppUnit is a C++ port of the JUnit testing framework developed by Erich Gamma and Kent Beck. This document describes the recent, stable version of CppUnit (we introduce version 1.12.1, and the latest version is 1.12.1). The main purpose of CppUnit is to support developers in doing their unit testing of C++ programs. This document assumes that you already have Visual Studio.

Preliminary

Download the local copy of CppUnit. Now, unpack the CppUnit archive file to a directory of your choice, in this example we assume it is D:\. The above command will create a new directory called 'D:/cppunit-1.12.1'. Simply go to D:/cppunit-1.12.1/src and open the CppUnitLibraries.sln in Visual Studio. Right-click on the cppunit project in the Solution Explorer pane and choose Build. After successful compilation, cppunit.lib is produced which we will use for our sample below.

Using CppUnit

Overview

In this section, we will provide you with some general steps on how to go about using CppUnit. The next section illustrates the key steps using an example. My advice is to skim through this section quickly for an overview. Then, as you go through the example in the next section, refer back to this section frequently to get the whole picture.

Assuming that you want to test a class called Parser. The following are the general steps to use the CppUnit framework to test this class:

  1. Write a class (let's call it TestParser) to test the Parser class. This class must inherit the class CPPUNIT_NS::TestFixture which is defined by the CppUnit framework.
  2. A test fixture is a set of sample objects that you want to (re)use during testing. For example, you might create a few sample source files for the Parser to parse. CppUnit provides a setUp and a tearDown method to manage the fixture. Therefore, you can create file objects in setUp to open the source files and release these resources in the tearDown method. The important thing to note is that setUp and tearDown will be called for every 'test' that you run.
  3. Each 'test' you perform is represented by the implementation of a method in the test class. For example, if you want to test whether the parser extracts the tokens correctly, you can implement a method called testGetToken. The collection of test methods you implement forms a test suite.
  4. In each test method you create, use the assertion mechanism provided by CppUnit to compare the results of running the test and the expected results. This will enable you to create repeatable tests as well as saving you lots of time from visually inspecting the results.
  5. Finally, use the textual version of the TestRunner tool to run the tests and collect the results. As each test is run, CppUnit will provide feedback on whether the test ran successfully, or the test failed, or an exception has occurred.

Example

In this section, we will describe how you can use CppUnit using an example (the reference section provides the link to download the sample files used for this guide). Take a few minutes to examine the following two classes (.h and .cpp files) to see what they are doing: Basically, there are two classes: Course and Student. Each Course contains a name eg. CS3215 and an integer grade which ranges from 0 to 100. Each Student has a name, a number as well as a list of course grades. You can add the grade that a student scores at a particular course using the assignGrade method and retrieve the grade of a particular course using the getGrade method.

Next, create the test class. The following are the test files we wrote for the Student class (called TestStudent.h and TestStudent.cpp):

Next create the main class to kick start the testing process.

Notes for the preceding code:

Create/Add the above source and header files in Visual Studio - C++ Win32 Console Application.

Modify default project settings, add references to include CppUnit library and header files and include a post-build unit testing command by setting the following from the menu bar:

  1. 'Project > Properties > C/C++ >  Code Generation > Runtime Library > Multi-threaded Debug DLL' (i.e. expand C/C++ tab, choose 'Code Generation' and choose 'Debug Multithreaded DLL' from 'Runtime Library' combo-box)
  2. Go to 'Project > Properties > C/C++ > General'. Put 'D:\cppunit-1.12.1\include' in the 'Additional Include Directories' text box.
  3. Go to 'Project > Properties > Linker > Input'. Put 'D:\cppunit-1.12.1\lib\cppunitd.lib' in the 'Additional Dependences' text box.
  4. Go to 'Project > Properties > Build Events > Post-Build Event'. Put '"$(TargetPath)"' in the 'Command Line' textbox . Put 'Unit Tests...' in the 'Description' textbox.

Run unit testing by building the project (press F6). The results of the unit tests will be displayed in the output tab add the bottom of the Visual Studio IDE. Alternatively, simply run the program by pressing F5.

Figure 1. Results of unit tests shown in Output tab

Exercise

The best way to learn CppUnit is to use it. So, here's a small exercise you can do to get some hands-on practice. Let's say we now extend the Student class by adding a method to find the average grade of all the courses taken by the student. You can add the following piece of code to Student.h and Student.cpp:
// In Student.h under public
// Method to return the average grade
float findAveGrade();

// In Student.cpp
// Method to return the average grade
float Student::findAveGrade() {
  float sum = 0.0, average;

  // sum up the marks in all the courses
  for (int i = 0; i < no_of_courses; i++)
    sum += course_grades[i].getCourseGrade();
  average = sum / no_of_courses;
  return(average);
}
Now write a method in the TestStudent class to test this newly created method. Give it a try and see whether you really know how to use CppUnit 

References