Programs: Getting Started with CppUnit in Ubuntu

When I was getting started using CppUnit on Linux, the tutorials were great--except that their code didn't compile. They just needed a couple of tweaks, of course. And of course since I was just getting started, it took forever to figure out which tweaks they needed. OK, I was pretty sure that include <stdafx.h> wasn't going to work on my Linux box, but the other stuff took longer to untangle. Anyhow, As of December 2007, here's a minimal example that worked/ran on my Ubuntu box.

Overview of the Files

Compiling and Running

Setup: don't forget to sudo aptitude install libcppunit-dev libcppunit-doc (but you probably already did that).

Compile: You can set things up with a Makefile, Automake file, etc. However you set things up, remember that you need to link cppunit. Here's a plain ol' command-line:

$ g++ -g CritterTest.cpp main.cc -lcppunit
$

Run: Let's take this thing out for a spin...

$ ./a.out
.F

CritterTest.cpp:11:Assertion
Test name: CritterTest::TestMemorySmoke
assertion failed
- Expression: m.AssociatedP(3)

Failures !!!
Run: 1   Failure total: 1   Failures: 1   Errors: 0

Hey, cool, looks like we found a bug.

File Contents

Critter.h is where my code lives. Except right now there's almost no real code. Soon there will be a Critter.cpp.

#ifndef CRITTER_H
#define CRITTER_H

typedef unsigned char CritterID;

// A critter's Memory of one other Critter
class Memory {
 public:
  // Is this who I'm thinking of?
  bool AssociatedP(CritterID otherID) { return otherID == this->otherID; } 

  // Constructors are awesome
  Memory(): otherID(0) {}

 private:
  CritterID otherID; // Who I'm thinking of
};

#endif /* CRITTER_H */

CritterTest.h is where I define my tests for things in Critter.h:

#ifndef CRITTERTEST_H
#define CRITTERTEST_H

#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>

class CritterTest : public CppUnit::TestFixture {
  CPPUNIT_TEST_SUITE( CritterTest );
  CPPUNIT_TEST( TestMemorySmoke );
  CPPUNIT_TEST_SUITE_END();

 public:
  void setUp(void) {}    // I don't use setUp or tearDown yet, but let's 
  void tearDown(void) {} // leave them in so I remember their names

  void TestMemorySmoke(void); 
};

#endif /* CRITTERTEST_H */

CritterTest.cpp does a couple of things: implements my memory smoke test and registers this set of tests.

#include <cppunit/extensions/HelperMacros.h>
#include "Critter.h"
#include "CritterTest.h"

CPPUNIT_TEST_SUITE_REGISTRATION( CritterTest );

void CritterTest::TestMemorySmoke(void) {
  Memory m;
  CPPUNIT_ASSERT(  m.AssociatedP(0) );
  CPPUNIT_ASSERT(! m.AssociatedP(42) );
  CPPUNIT_ASSERT(  m.AssociatedP(3) ); /* this should fail */
}

main.cc Has my main function. Right now, my program doesn't do anything other than run its tests. Someday, maybe I'll set up a separate testing version, but for now this is just fine. This is mostly stolen from the official tutorial, but doesn't try to use a nonexistent TestRunner.

#include "Critter.h"
#include "CritterTest.h"
#include <cppunit/CompilerOutputter.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
// #include <cppunit/ui/text/TestRunner.h> /* deprecated argh */
#include <cppunit/ui/text/TextTestRunner.h>

int RunTests(void) 
{
  // Get the top level suite from the registry
  CppUnit::Test *suite = CppUnit::TestFactoryRegistry::getRegistry().makeTest();

  // Adds the test to the list of test to run
  // CppUnit::TextUi::TestRunner runner;
  CppUnit::TextTestRunner runner;
  runner.addTest( suite );

  // Change the default outputter to a compiler error format outputter
  runner.setOutputter( new CppUnit::CompilerOutputter( &runner.result(),
                                                       std::cerr ) );
  // Run the tests.
  bool wasSucessful = runner.run();

  // Return error code 1 if the one of test failed.
  return wasSucessful ? 0 : 1;
}

int main(void) {
  return RunTests();
}

This worked for me. I hope it works for you.

[^]

comment? | | home |