CppUnit Description:
The CppUnit test framework is for unit test of C++ class functions.
It relies on the hierarchy of a test suite comprising of unit test cases which test class functions.
The test begins with setUp() followed by the test and ending with tearDown().
Each unit test employs the use of C++ assert() to test the function results.
C++ assert prototype: void assert (int expression);
If this expression evaluates to 0, this causes an assertion failure that terminates the program.
The assert function will abort the application if false.
Turn assert off: #define NDEBUG
at the beginning of its code, before the inclusion of assert.h
Also see the YoLinux Tutorial on Google C++ unit test.
Man page:
- assert - abort the program if assertion is false
Installation:
Available as Linux RPMs:
- cppunit-1.12.0-3.el5.rf
- cppunit-devel-1.12.0-3.el5.rf
Docs installed to:
/usr/share/doc/doc/cppunit-devel-1.12.0/index.html
Debian/Ubuntu: apt-get install libcppunit-doc libcppunit-dev
CppUnit Home Page
CppUnit Example:
C++ class to unit test:
File:
CBasicMath.hpp
01 | #ifndef BASIC_MATH_HPP__ |
02 | #define BASIC_MATH_HPP__ |
07 | int Addition( int x, int y); |
08 | int Multiply( int x, int y); |
File:
CBasicMath.cpp
01 | #include "CBasicMath.hpp" |
03 | int CBasicMath::Addition( int x, int y) |
08 | int CBasicMath::Multiply( int x, int y) |
CppUnit test driver program:
File:
TestBasicMath.cpp
004 | #include <cppunit/TestCase.h> |
005 | #include <cppunit/TestFixture.h> |
006 | #include <cppunit/ui/text/TextTestRunner.h> |
007 | #include <cppunit/extensions/HelperMacros.h> |
008 | #include <cppunit/extensions/TestFactoryRegistry.h> |
009 | #include <cppunit/TestResult.h> |
010 | #include <cppunit/TestResultCollector.h> |
011 | #include <cppunit/TestRunner.h> |
012 | #include <cppunit/BriefTestProgressListener.h> |
013 | #include <cppunit/CompilerOutputter.h> |
014 | #include <cppunit/XmlOutputter.h> |
015 | #include <netinet/in.h> |
017 | #include "CBasicMath.hpp" |
019 | using namespace CppUnit; |
024 | class TestBasicMath : public CppUnit::TestFixture |
026 | CPPUNIT_TEST_SUITE(TestBasicMath); |
027 | CPPUNIT_TEST(testAddition); |
028 | CPPUNIT_TEST(testMultiply); |
029 | CPPUNIT_TEST_SUITE_END(); |
036 | void testAddition( void ); |
037 | void testMultiply( void ); |
041 | CBasicMath *mTestObj; |
047 | TestBasicMath::testAddition( void ) |
049 | CPPUNIT_ASSERT(5 == mTestObj->Addition(2,3)); |
053 | TestBasicMath::testMultiply( void ) |
055 | CPPUNIT_ASSERT(6 == mTestObj->Multiply(2,3)); |
058 | void TestBasicMath::setUp( void ) |
060 | mTestObj = new CBasicMath(); |
063 | void TestBasicMath::tearDown( void ) |
070 | CPPUNIT_TEST_SUITE_REGISTRATION( TestBasicMath ); |
072 | int main( int argc, char * argv[]) |
075 | CPPUNIT_NS::TestResult testresult; |
078 | CPPUNIT_NS::TestResultCollector collectedresults; |
079 | testresult.addListener (&collectedresults); |
082 | CPPUNIT_NS::BriefTestProgressListener progress; |
083 | testresult.addListener (&progress); |
086 | CPPUNIT_NS::TestRunner testrunner; |
087 | testrunner.addTest (CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest ()); |
088 | testrunner.run(testresult); |
091 | CPPUNIT_NS::CompilerOutputter compileroutputter(&collectedresults, std::cerr); |
092 | compileroutputter.write (); |
095 | ofstream xmlFileOut( "cppTestBasicMathResults.xml" ); |
096 | XmlOutputter xmlOut(&collectedresults, xmlFileOut); |
100 | return collectedresults.wasSuccessful() ? 0 : 1; |
Note the use of XmlOutputter for XML output of results
Compile:
g++ -o testBasicMath CBasicMath.cpp TestBasicMath.cpp -lcppunit
File:
Makefile
03 | CXXFLAGS = -g $(INCLUDES) |
04 | SRCM= ../CBasicMath.cpp |
08 | testbasicmath: TestBasicMath.cpp $(OBJM) |
09 | $(CXX) $(CXXFLAGS) -o $@ TestBasicMath.cpp $(OBJM) $(LINKFLAGS) $(LINKFLAGSLOG4) $(LIBLOG) |
14 | $(CXX) $(CXXFLAGS) -c $< -o $@ |
Run test: ./testBasicMath
TestBasicMath::testAddition : OK
TestBasicMath::testMultiply : OK
This generates the XML file:
cppTestBasicMathResults.xml
01 | <? xml version = "1.0" encoding = 'ISO-8859-1' standalone = 'yes' ?> |
03 | < FailedTests ></ FailedTests > |
06 | < Name >TestBasicMath::testAddition</ Name > |
09 | < Name >TestBasicMath::testMultiply</ Name > |
14 | < FailuresTotal >0</ FailuresTotal > |
16 | < Failures >0</ Failures > |
Integration with Jenkins:
Note that I had no luck with the CppUnit plugin for Jenkins and integration required explicit translation of XML unit test results to JUnit format for use by Jenkins.
Ant script to execute Makefile:
File:
build.xml
01 | < property name = "make.cmd" value = "/usr/bin/make" /> |
07 | < target name = "testBasicMathCompile" |
08 | description = "cppunit test compile" > |
09 | < exec dir = "${build.native}/Test" executable = "${make.cmd}" failonerror = "true" > |
11 | < arg value = "testbasicmath" /> |
15 | < target name = "testbasicmath" |
16 | description = "cppunit test run" > |
17 | < exec dir = "${build.native}/Test" executable = "./testbasicmath" failonerror = "false" > |
The XML results of CppUnit require translation to JUnit style XML for interpretation by Jenkins.
Requires XML conversion from CPP Unit to JUnit using XSLT: cpp2junit.xslt
File:
cpp2junit.xslt
01 | <? xml version = "1.0" encoding = "UTF-8" ?> |
03 | < xsl:output method = "xml" indent = "yes" /> |
04 | < xsl:template match = "/" > |
06 | < xsl:attribute name = "errors" >< xsl:value-of select = "TestRun/Statistics/Errors" /></ xsl:attribute > |
07 | < xsl:attribute name = "failures" > |
08 | < xsl:value-of select = "TestRun/Statistics/Failures" /> |
10 | < xsl:attribute name = "tests" > |
11 | < xsl:value-of select = "TestRun/Statistics/Tests" /> |
13 | < xsl:attribute name = "name" >from cppunit</ xsl:attribute > |
14 | < xsl:apply-templates /> |
17 | < xsl:template match = "/TestRun/SuccessfulTests/Test" > |
19 | < xsl:attribute name = "classname" >< xsl:value-of select = "substring-before(Name, '::')" /></ xsl:attribute > |
20 | < xsl:attribute name = "name" >< xsl:value-of select = "substring-after(Name, '::')" /></ xsl:attribute > |
23 | < xsl:template match = "/TestRun/FailedTests/FailedTest" > |
25 | < xsl:attribute name = "classname" >< xsl:value-of select = "substring-before(Name, '::')" /></ xsl:attribute > |
26 | < xsl:attribute name = "name" >< xsl:value-of select = "substring-after(Name, '::')" /></ xsl:attribute > |
28 | < xsl:attribute name = "message" > |
29 | < xsl:value-of select = " normalize-space(Message)" /> |
31 | < xsl:attribute name = "type" > |
32 | < xsl:value-of select = "FailureType" /> |
34 | < xsl:value-of select = "Message" /> |
35 | File:< xsl:value-of select = "Location/File" /> |
36 | Line:< xsl:value-of select = "Location/Line" /> |
40 | < xsl:template match = "text()|@*" /> |
Use the Gnome program "xsltproc" to apply XSLT to the CppUnit output XML.
Command: xsltproc -o junitTestBasicMathResults.xml cpp2junit.xslt cppTestBasicMathResults.xml
Translated results:
junitTestBasicMathResults.xml
2 | < testsuite errors = "0" failures = "0" tests = "2" name = "from cppunit" > |
3 | < testcase classname = "TestBasicMath" name = "testAddition" /> |
4 | < testcase classname = "TestBasicMath" name = "testMultiply" /> |
Ant script for results translation:
File:
build.xml
01 | < property name = "xsltproc.cmd" value = "/usr/bin/xsltproc" /> |
07 | < target name = "testdbCpp2junit" |
08 | description = "Convert cppunit test results to junit test results" > |
09 | < echo >Tests run from directory: ${build.native}/Test</ echo > |
10 | < exec dir = "${build.native}/Test" executable = "${xsltproc.cmd}" failonerror = "true" > |
13 | < arg value = "test/data/junitTestBasicMathResults.xml" /> |
14 | < arg value = "cpp2junit.xslt" /> |
15 | < arg value = "cppTestBasicMathResults.xml" /> |
xsltproc man page - command line XSLT processor
Jenkins configuration to display JUnit results:
Configuration
For more, see the YoLinux.com Jenkins tutorial

Books: