Using CxxTest

Unit Testing 2 of 3

Having compared the two most popular C++ unit testing frameworks, let’s move on to the next step – the actual usage. Personally I prefer CxxTest, that’s why the samples bellow demonstrate its use. The test target will be the sample implementation of a read-only memory mapping.

Writing the tests

The sample project, that needs to be tested, contains two classes that implement a common interface. This simplifies our task, cause we need to write only one test class. In CxxTest the test suites are derived from the CxxTest::TestSuite class:

#include <cxxtest/TestSuite.h>

class CMemoryMappingTest : public CxxTest::TestSuite

A test suite should be self-sufficient, i.e. it should not rely on external resources (like the presence of files, etc.). That’s why the constructor of CMemoryMappingTest is creating a text file and the destructor deletes it.
Each test should be executed in isolation, so we use setUp() and tearDown() to achieve this. setUp() is called before each test, and tearDown() after.

We can test

  • if creating an instance of the class causes an exception (it is not supposed to);
  • and if it returns a non-null pointer.
void testConstruction()
{
	TS_ASSERT_THROWS_NOTHING(pMemoryMapping = CMemoryMapping::instantiate())
	TS_ASSERT_DIFFERS((void*)0,pMemoryMapping)
}

An exception should never be thrown from a destructor, that’s why we make sure that the destructor doesn’t throw.

void testDestructor()
{
	TS_ASSERT_THROWS_NOTHING(delete m_pMemoryMapping)
}

After we are sure that the class can be safely constructed and destructed, we can move on to testing its methods.

The open() method is tested with a valid file (positive test case) and non-existing file (negative test case).

void testOpen()
{
	TS_ASSERT_THROWS_NOTHING(m_pMemoryMapping->open(pszTestFile));
	TS_ASSERT_THROWS(m_pMemoryMapping->open(pszInvalidTestFile),std::ios::failure);
	TS_ASSERT_THROWS(m_pMemoryMapping->open(""),std::ios::failure);
}

size() returns the size of the mapped data, so we make sure that it matches.

void testSize()
{
	TS_ASSERT_EQUALS(m_pMemoryMapping->size(),strlen(pszTestData));
}

The test of the data() method compares the data returned by the mapping class to the source data, written to the file beforehand.

void testData()
{
	TS_ASSERT_EQUALS(memcmp(m_pMemoryMapping->data(),pszTestData,m_pMemoryMapping->size()),0);
}

Invoking the close() method should never cause an exception:

void testClose()
{
	TS_ASSERT_THROWS_NOTHING(m_pMemoryMapping->close());
}

In order to use the test, it should be integrated with a build environment. On Windows I prefer to use Microsoft Visual Studio and Autotools on Linux/Unix-like OSs (remember “When in Rome, do as the Romans do” ūüôā ).

You can leave a response, or trackback from your own site.

Leave a Reply