|
Packit Service |
e31359 |
/*! \page cppunit_cookbook CppUnit Cookbook
|
|
Packit Service |
e31359 |
Here is a short cookbook to help you get started.
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
\section simple_test_case Simple Test Case
|
|
Packit Service |
e31359 |
You want to know whether your code is working.
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
How do you do it?
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
There are many ways. Stepping through a debugger or
|
|
Packit Service |
e31359 |
littering your code with stream output calls are two of
|
|
Packit Service |
e31359 |
the simpler ways, but they both have drawbacks.
|
|
Packit Service |
e31359 |
Stepping through your code is a good idea, but it
|
|
Packit Service |
e31359 |
is not automatic. You have to do it every time you
|
|
Packit Service |
e31359 |
make changes. Streaming out text is also fine,
|
|
Packit Service |
e31359 |
but it makes code ugly and it generates far more
|
|
Packit Service |
e31359 |
information than you need most of the time.
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
Tests in %CppUnit can be run automatically.
|
|
Packit Service |
e31359 |
They are easy to set up and once you have
|
|
Packit Service |
e31359 |
written them, they are always there to help
|
|
Packit Service |
e31359 |
you keep confidence in the quality of your code.
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
To make a simple test, here is what you do:
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
Subclass the \link CppUnit::TestCase TestCase \endlink class.
|
|
Packit Service |
e31359 |
Override the method \link CppUnit::TestCase::runTest() runTest()\endlink.
|
|
Packit Service |
e31359 |
When you want to check a value, call
|
|
Packit Service |
e31359 |
\link CPPUNIT_ASSERT() CPPUNIT_ASSERT(bool) \endlink
|
|
Packit Service |
e31359 |
and pass in an expression that is true if the
|
|
Packit Service |
e31359 |
test succeeds.
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
For example, to test the equality comparison
|
|
Packit Service |
e31359 |
for a Complex number class, write:
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
\code
|
|
Packit Service |
e31359 |
class ComplexNumberTest : public CppUnit::TestCase {
|
|
Packit Service |
e31359 |
public:
|
|
Packit Service |
e31359 |
ComplexNumberTest( std::string name ) : CppUnit::TestCase( name ) {}
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
void runTest() {
|
|
Packit Service |
e31359 |
CPPUNIT_ASSERT( Complex (10, 1) == Complex (10, 1) );
|
|
Packit Service |
e31359 |
CPPUNIT_ASSERT( !(Complex (1, 1) == Complex (2, 2)) );
|
|
Packit Service |
e31359 |
}
|
|
Packit Service |
e31359 |
};
|
|
Packit Service |
e31359 |
\endcode
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
That was a very simple test. Ordinarily,
|
|
Packit Service |
e31359 |
you'll have many little test cases that you'll
|
|
Packit Service |
e31359 |
want to run on the same set of objects. To do
|
|
Packit Service |
e31359 |
this, use a fixture.
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
\section fixture Fixture
|
|
Packit Service |
e31359 |
A fixture is a known set of objects that
|
|
Packit Service |
e31359 |
serves as a base for a set of test cases.
|
|
Packit Service |
e31359 |
Fixtures come in very handy when you are
|
|
Packit Service |
e31359 |
testing as you develop.
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
Let's try out this style of development and
|
|
Packit Service |
e31359 |
learn about fixtures along the away. Suppose
|
|
Packit Service |
e31359 |
that we are really developing a complex
|
|
Packit Service |
e31359 |
number class. Let's start by defining a
|
|
Packit Service |
e31359 |
empty class named Complex.
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
\code
|
|
Packit Service |
e31359 |
class Complex {};
|
|
Packit Service |
e31359 |
\endcode
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
Now create an instance of ComplexNumberTest
|
|
Packit Service |
e31359 |
above, compile the code and see what happens.
|
|
Packit Service |
e31359 |
The first thing we notice is a few compiler
|
|
Packit Service |
e31359 |
errors. The test uses <tt>operator ==</tt>, but it is
|
|
Packit Service |
e31359 |
not defined. Let's fix that.
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
\code
|
|
Packit Service |
e31359 |
bool operator==( const Complex &a, const Complex &b)
|
|
Packit Service |
e31359 |
{
|
|
Packit Service |
e31359 |
return true;
|
|
Packit Service |
e31359 |
}
|
|
Packit Service |
e31359 |
\endcode
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
Now compile the test, and run it. This time it
|
|
Packit Service |
e31359 |
compiles but the test fails.
|
|
Packit Service |
e31359 |
We need a bit more to get an <tt>operator ==</tt>working
|
|
Packit Service |
e31359 |
correctly, so we revisit the code.
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
\code
|
|
Packit Service |
e31359 |
class Complex {
|
|
Packit Service |
e31359 |
friend bool operator ==(const Complex& a, const Complex& b);
|
|
Packit Service |
e31359 |
double real, imaginary;
|
|
Packit Service |
e31359 |
public:
|
|
Packit Service |
e31359 |
Complex( double r, double i = 0 )
|
|
Packit Service |
e31359 |
: real(r)
|
|
Packit Service |
e31359 |
, imaginary(i)
|
|
Packit Service |
e31359 |
{
|
|
Packit Service |
e31359 |
}
|
|
Packit Service |
e31359 |
};
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
bool operator ==( const Complex &a, const Complex &b )
|
|
Packit Service |
e31359 |
{
|
|
Packit Service |
e31359 |
return a.real == b.real && a.imaginary == b.imaginary;
|
|
Packit Service |
e31359 |
}
|
|
Packit Service |
e31359 |
\endcode
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
If we compile now and run our test it will pass.
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
Now we are ready to add new operations and
|
|
Packit Service |
e31359 |
new tests. At this point a fixture would be
|
|
Packit Service |
e31359 |
handy. We would probably be better off when
|
|
Packit Service |
e31359 |
doing our tests if we decided to instantiate
|
|
Packit Service |
e31359 |
three or four complex numbers and reuse them
|
|
Packit Service |
e31359 |
across our tests.
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
Here is how we do it:
|
|
Packit Service |
e31359 |
- Add member variables for each part of the
|
|
Packit Service |
e31359 |
\link CppUnit::TestFixture fixture \endlink
|
|
Packit Service |
e31359 |
- Override \link CppUnit::TestFixture::setUp() setUp() \endlink
|
|
Packit Service |
e31359 |
to initialize the variables
|
|
Packit Service |
e31359 |
- Override \link CppUnit::TestFixture::tearDown() tearDown() \endlink
|
|
Packit Service |
e31359 |
to release any permanent resources you allocated in
|
|
Packit Service |
e31359 |
\link CppUnit::TestFixture::setUp() setUp() \endlink
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
\code
|
|
Packit Service |
e31359 |
class ComplexNumberTest : public CppUnit::TestFixture {
|
|
Packit Service |
e31359 |
private:
|
|
Packit Service |
e31359 |
Complex *m_10_1, *m_1_1, *m_11_2;
|
|
Packit Service |
e31359 |
public:
|
|
Packit Service |
e31359 |
void setUp()
|
|
Packit Service |
e31359 |
{
|
|
Packit Service |
e31359 |
m_10_1 = new Complex( 10, 1 );
|
|
Packit Service |
e31359 |
m_1_1 = new Complex( 1, 1 );
|
|
Packit Service |
e31359 |
m_11_2 = new Complex( 11, 2 );
|
|
Packit Service |
e31359 |
}
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
void tearDown()
|
|
Packit Service |
e31359 |
{
|
|
Packit Service |
e31359 |
delete m_10_1;
|
|
Packit Service |
e31359 |
delete m_1_1;
|
|
Packit Service |
e31359 |
delete m_11_2;
|
|
Packit Service |
e31359 |
}
|
|
Packit Service |
e31359 |
};
|
|
Packit Service |
e31359 |
\endcode
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
Once we have this fixture, we can add the complex
|
|
Packit Service |
e31359 |
addition test case and any others that we need
|
|
Packit Service |
e31359 |
over the course of our development.
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
\section test_case Test Case
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
How do you write and invoke individual tests using a fixture?
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
There are two steps to this process:
|
|
Packit Service |
e31359 |
- Write the test case as a method in the fixture class
|
|
Packit Service |
e31359 |
- Create a TestCaller which runs that particular method
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
Here is our test case class with a few extra case methods:
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
\code
|
|
Packit Service |
e31359 |
class ComplexNumberTest : public CppUnit::TestFixture {
|
|
Packit Service |
e31359 |
private:
|
|
Packit Service |
e31359 |
Complex *m_10_1, *m_1_1, *m_11_2;
|
|
Packit Service |
e31359 |
public:
|
|
Packit Service |
e31359 |
void setUp()
|
|
Packit Service |
e31359 |
{
|
|
Packit Service |
e31359 |
m_10_1 = new Complex( 10, 1 );
|
|
Packit Service |
e31359 |
m_1_1 = new Complex( 1, 1 );
|
|
Packit Service |
e31359 |
m_11_2 = new Complex( 11, 2 );
|
|
Packit Service |
e31359 |
}
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
void tearDown()
|
|
Packit Service |
e31359 |
{
|
|
Packit Service |
e31359 |
delete m_10_1;
|
|
Packit Service |
e31359 |
delete m_1_1;
|
|
Packit Service |
e31359 |
delete m_11_2;
|
|
Packit Service |
e31359 |
}
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
void testEquality()
|
|
Packit Service |
e31359 |
{
|
|
Packit Service |
e31359 |
CPPUNIT_ASSERT( *m_10_1 == *m_10_1 );
|
|
Packit Service |
e31359 |
CPPUNIT_ASSERT( !(*m_10_1 == *m_11_2) );
|
|
Packit Service |
e31359 |
}
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
void testAddition()
|
|
Packit Service |
e31359 |
{
|
|
Packit Service |
e31359 |
CPPUNIT_ASSERT( *m_10_1 + *m_1_1 == *m_11_2 );
|
|
Packit Service |
e31359 |
}
|
|
Packit Service |
e31359 |
};
|
|
Packit Service |
e31359 |
\endcode
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
One may create and run instances for each test case like this:
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
\code
|
|
Packit Service |
e31359 |
CppUnit::TestCaller<ComplexNumberTest> test( "testEquality",
|
|
Packit Service |
e31359 |
&ComplexNumberTest::testEquality );
|
|
Packit Service |
e31359 |
CppUnit::TestResult result;
|
|
Packit Service |
e31359 |
test.run( &result );
|
|
Packit Service |
e31359 |
\endcode
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
The second argument to the test caller constructor is the address of
|
|
Packit Service |
e31359 |
a method on ComplexNumberTest. When the test caller is run,
|
|
Packit Service |
e31359 |
that specific method will be run. This is not a useful thing to do,
|
|
Packit Service |
e31359 |
however, as no diagnostics will be displayed.
|
|
Packit Service |
e31359 |
One will normally use a \link ExecutingTest TestRunner \endlink (see below)
|
|
Packit Service |
e31359 |
to display the results.
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
Once you have several tests, organize them into a suite.
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
\section suite Suite
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
How do you set up your tests so that you can run them all at once?
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
%CppUnit provides a \link CppUnit::TestSuite TestSuite \endlink class
|
|
Packit Service |
e31359 |
that runs any number of TestCases together.
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
We saw, above, how to run a single test case.
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
To create a suite of two or more tests, you do the following:
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
\code
|
|
Packit Service |
e31359 |
CppUnit::TestSuite suite;
|
|
Packit Service |
e31359 |
CppUnit::TestResult result;
|
|
Packit Service |
e31359 |
suite.addTest( new CppUnit::TestCaller<ComplexNumberTest>(
|
|
Packit Service |
e31359 |
"testEquality",
|
|
Packit Service |
e31359 |
&ComplexNumberTest::testEquality ) );
|
|
Packit Service |
e31359 |
suite.addTest( new CppUnit::TestCaller<ComplexNumberTest>(
|
|
Packit Service |
e31359 |
"testAddition",
|
|
Packit Service |
e31359 |
&ComplexNumberTest::testAddition ) );
|
|
Packit Service |
e31359 |
suite.run( &result );
|
|
Packit Service |
e31359 |
\endcode
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
\link CppUnit::TestSuite TestSuites \endlink don't only have to
|
|
Packit Service |
e31359 |
contain callers for TestCases. They can contain any object
|
|
Packit Service |
e31359 |
that implements the \link CppUnit::Test Test \endlink interface.
|
|
Packit Service |
e31359 |
For example, you can create a
|
|
Packit Service |
e31359 |
\link CppUnit::TestSuite TestSuite \endlink in your code and
|
|
Packit Service |
e31359 |
I can create one in mine, and we can run them together
|
|
Packit Service |
e31359 |
by creating a \link CppUnit::TestSuite TestSuite \endlink
|
|
Packit Service |
e31359 |
that contains both:
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
\code
|
|
Packit Service |
e31359 |
CppUnit::TestSuite suite;
|
|
Packit Service |
e31359 |
CppUnit::TestResult result;
|
|
Packit Service |
e31359 |
suite.addTest( ComplexNumberTest::suite() );
|
|
Packit Service |
e31359 |
suite.addTest( SurrealNumberTest::suite() );
|
|
Packit Service |
e31359 |
suite.run( &result );
|
|
Packit Service |
e31359 |
\endcode
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
\section test_runner TestRunner
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
How do you run your tests and collect their results?
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
Once you have a test suite, you'll want to run it. %CppUnit provides tools
|
|
Packit Service |
e31359 |
to define the suite to be run and to display its results.
|
|
Packit Service |
e31359 |
You make your suite accessible to a \link ExecutingTest TestRunner \endlink
|
|
Packit Service |
e31359 |
program with a static method suite that returns a test suite.
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
For example, to make a ComplexNumberTest suite available to a
|
|
Packit Service |
e31359 |
\link ExecutingTest TestRunner \endlink, add the following code to
|
|
Packit Service |
e31359 |
ComplexNumberTest:
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
\code
|
|
Packit Service |
e31359 |
public:
|
|
Packit Service |
e31359 |
static CppUnit::TestSuite *suite()
|
|
Packit Service |
e31359 |
{
|
|
Packit Service |
e31359 |
CppUnit::TestSuite *suiteOfTests = new CppUnit::TestSuite( "ComplexNumberTest" );
|
|
Packit Service |
e31359 |
suiteOfTests->addTest( new CppUnit::TestCaller<ComplexNumberTest>(
|
|
Packit Service |
e31359 |
"testEquality",
|
|
Packit Service |
e31359 |
&ComplexNumberTest::testEquality ) );
|
|
Packit Service |
e31359 |
suiteOfTests->addTest( new CppUnit::TestCaller<ComplexNumberTest>(
|
|
Packit Service |
e31359 |
"testAddition",
|
|
Packit Service |
e31359 |
&ComplexNumberTest::testAddition ) );
|
|
Packit Service |
e31359 |
return suiteOfTests;
|
|
Packit Service |
e31359 |
}
|
|
Packit Service |
e31359 |
\endcode
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
\anchor test_runner_code
|
|
Packit Service |
e31359 |
To use the text version, include the header files for the tests in Main.cpp:
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
\code
|
|
Packit Service |
e31359 |
#include <cppunit/ui/text/TestRunner.h>
|
|
Packit Service |
e31359 |
#include "ExampleTestCase.h"
|
|
Packit Service |
e31359 |
#include "ComplexNumberTest.h"
|
|
Packit Service |
e31359 |
\endcode
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
And add a call to
|
|
Packit Service |
e31359 |
\link ::CppUnit::TextUi::TestRunner::addTest addTest(CppUnit::Test *) \endlink
|
|
Packit Service |
e31359 |
in the <tt>main()</tt> function:
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
\code
|
|
Packit Service |
e31359 |
int main( int argc, char **argv)
|
|
Packit Service |
e31359 |
{
|
|
Packit Service |
e31359 |
CppUnit::TextUi::TestRunner runner;
|
|
Packit Service |
e31359 |
runner.addTest( ExampleTestCase::suite() );
|
|
Packit Service |
e31359 |
runner.addTest( ComplexNumberTest::suite() );
|
|
Packit Service |
e31359 |
runner.run();
|
|
Packit Service |
e31359 |
return 0;
|
|
Packit Service |
e31359 |
}
|
|
Packit Service |
e31359 |
\endcode
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
The \link ExecutingTest TestRunner \endlink will run the tests.
|
|
Packit Service |
e31359 |
If all the tests pass, you'll get an informative message.
|
|
Packit Service |
e31359 |
If any fail, you'll get the following information:
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
- The name of the test case that failed
|
|
Packit Service |
e31359 |
- The name of the source file that contains the test
|
|
Packit Service |
e31359 |
- The line number where the failure occurred
|
|
Packit Service |
e31359 |
- All of the text inside the call to CPPUNIT_ASSERT() which detected the failure
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
%CppUnit distinguishes between failures and errors. A failure is
|
|
Packit Service |
e31359 |
anticipated and checked for with assertions. Errors are unanticipated problems
|
|
Packit Service |
e31359 |
like division by zero and other exceptions thrown by the C++ runtime or your code.
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
\section helper_macros Helper Macros
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
As you might have noticed, implementing the fixture static <tt>suite()</tt>
|
|
Packit Service |
e31359 |
method is a repetitive and error prone task. A \ref WritingTestFixture set of
|
|
Packit Service |
e31359 |
macros have been created to automatically implements the
|
|
Packit Service |
e31359 |
static <tt>suite()</tt> method.
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
The following code is a rewrite of ComplexNumberTest using those macros:
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
\code
|
|
Packit Service |
e31359 |
#include <cppunit/extensions/HelperMacros.h>
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
class ComplexNumberTest : public CppUnit::TestFixture {
|
|
Packit Service |
e31359 |
\endcode
|
|
Packit Service |
e31359 |
First, we declare the suite, passing the class name to the macro:
|
|
Packit Service |
e31359 |
\code
|
|
Packit Service |
e31359 |
CPPUNIT_TEST_SUITE( ComplexNumberTest );
|
|
Packit Service |
e31359 |
\endcode
|
|
Packit Service |
e31359 |
The suite created by the static <tt>suite()</tt> method is named after
|
|
Packit Service |
e31359 |
the class name.
|
|
Packit Service |
e31359 |
Then, we declare each test case of the fixture:
|
|
Packit Service |
e31359 |
\code
|
|
Packit Service |
e31359 |
CPPUNIT_TEST( testEquality );
|
|
Packit Service |
e31359 |
CPPUNIT_TEST( testAddition );
|
|
Packit Service |
e31359 |
\endcode
|
|
Packit Service |
e31359 |
Finally, we end the suite declaration:
|
|
Packit Service |
e31359 |
\code
|
|
Packit Service |
e31359 |
CPPUNIT_TEST_SUITE_END();
|
|
Packit Service |
e31359 |
\endcode
|
|
Packit Service |
e31359 |
At this point, a method with the following signature has been implemented:
|
|
Packit Service |
e31359 |
\code
|
|
Packit Service |
e31359 |
static CppUnit::TestSuite *suite();
|
|
Packit Service |
e31359 |
\endcode
|
|
Packit Service |
e31359 |
The rest of the fixture is left unchanged:
|
|
Packit Service |
e31359 |
\code
|
|
Packit Service |
e31359 |
private:
|
|
Packit Service |
e31359 |
Complex *m_10_1, *m_1_1, *m_11_2;
|
|
Packit Service |
e31359 |
public:
|
|
Packit Service |
e31359 |
void setUp()
|
|
Packit Service |
e31359 |
{
|
|
Packit Service |
e31359 |
m_10_1 = new Complex( 10, 1 );
|
|
Packit Service |
e31359 |
m_1_1 = new Complex( 1, 1 );
|
|
Packit Service |
e31359 |
m_11_2 = new Complex( 11, 2 );
|
|
Packit Service |
e31359 |
}
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
void tearDown()
|
|
Packit Service |
e31359 |
{
|
|
Packit Service |
e31359 |
delete m_10_1;
|
|
Packit Service |
e31359 |
delete m_1_1;
|
|
Packit Service |
e31359 |
delete m_11_2;
|
|
Packit Service |
e31359 |
}
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
void testEquality()
|
|
Packit Service |
e31359 |
{
|
|
Packit Service |
e31359 |
CPPUNIT_ASSERT( *m_10_1 == *m_10_1 );
|
|
Packit Service |
e31359 |
CPPUNIT_ASSERT( !(*m_10_1 == *m_11_2) );
|
|
Packit Service |
e31359 |
}
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
void testAddition()
|
|
Packit Service |
e31359 |
{
|
|
Packit Service |
e31359 |
CPPUNIT_ASSERT( *m_10_1 + *m_1_1 == *m_11_2 );
|
|
Packit Service |
e31359 |
}
|
|
Packit Service |
e31359 |
};
|
|
Packit Service |
e31359 |
\endcode
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
The name of the \link CppUnit::TestCaller TestCaller \endlink added to the
|
|
Packit Service |
e31359 |
suite are a composition of the fixture name and the method name.
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
In the present case, the names would be:
|
|
Packit Service |
e31359 |
"ComplexNumberTest.testEquality" and "ComplexNumberTest.testAddition".
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
The \link WritingTestFixture helper macros \endlink help you write comon assertion.
|
|
Packit Service |
e31359 |
For example, to check that ComplexNumber throws a MathException when dividing
|
|
Packit Service |
e31359 |
a number by 0:
|
|
Packit Service |
e31359 |
- add the test to the suite using CPPUNIT_TEST_EXCEPTION, specifying the expected
|
|
Packit Service |
e31359 |
exception type.
|
|
Packit Service |
e31359 |
- write the test case method
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
\code
|
|
Packit Service |
e31359 |
CPPUNIT_TEST_SUITE( ComplexNumberTest );
|
|
Packit Service |
e31359 |
// [...]
|
|
Packit Service |
e31359 |
CPPUNIT_TEST_EXCEPTION( testDivideByZeroThrows, MathException );
|
|
Packit Service |
e31359 |
CPPUNIT_TEST_SUITE_END();
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
// [...]
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
void testDivideByZeroThrows()
|
|
Packit Service |
e31359 |
{
|
|
Packit Service |
e31359 |
// The following line should throw a MathException.
|
|
Packit Service |
e31359 |
*m_10_1 / ComplexNumber(0);
|
|
Packit Service |
e31359 |
}
|
|
Packit Service |
e31359 |
\endcode
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
If the expected exception is not thrown, then a assertion failure is reported.
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
\section test_factory_registry TestFactoryRegistry
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
The TestFactoryRegistry was created to solve two pitfalls:
|
|
Packit Service |
e31359 |
- forgetting to add your fixture suite to the test runner (since it is in
|
|
Packit Service |
e31359 |
another file, it is easy to forget)
|
|
Packit Service |
e31359 |
- compilation bottleneck caused by the inclusion of all test case headers
|
|
Packit Service |
e31359 |
(see \ref test_runner_code "previous example")
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
The TestFactoryRegistry is a place where suites can be registered at initialization
|
|
Packit Service |
e31359 |
time.
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
To register the ComplexNumber suite, in the .cpp file, you add:
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
\code
|
|
Packit Service |
e31359 |
#include <cppunit/extensions/HelperMacros.h>
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
CPPUNIT_TEST_SUITE_REGISTRATION( ComplexNumberTest );
|
|
Packit Service |
e31359 |
\endcode
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
Behind the scene, a static variable type of
|
|
Packit Service |
e31359 |
\link CppUnit::AutoRegisterSuite AutoRegisterSuite \endlink is declared.
|
|
Packit Service |
e31359 |
On construction, it will
|
|
Packit Service |
e31359 |
\link CppUnit::TestFactoryRegistry::registerFactory(TestFactory*) register \endlink
|
|
Packit Service |
e31359 |
a \link CppUnit::TestSuiteFactory TestSuiteFactory \endlink into the
|
|
Packit Service |
e31359 |
\link CppUnit::TestFactoryRegistry TestFactoryRegistry \endlink.
|
|
Packit Service |
e31359 |
The \link CppUnit::TestSuiteFactory TestSuiteFactory \endlink returns
|
|
Packit Service |
e31359 |
the \link CppUnit::TestSuite TestSuite \endlink returned by ComplexNumber::suite().
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
To run the tests, using the text test runner, we don't need to include the fixture
|
|
Packit Service |
e31359 |
anymore:
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
\code
|
|
Packit Service |
e31359 |
#include <cppunit/extensions/TestFactoryRegistry.h>
|
|
Packit Service |
e31359 |
#include <cppunit/ui/text/TestRunner.h>
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
int main( int argc, char **argv)
|
|
Packit Service |
e31359 |
{
|
|
Packit Service |
e31359 |
CppUnit::TextUi::TestRunner runner;
|
|
Packit Service |
e31359 |
\endcode
|
|
Packit Service |
e31359 |
First, we retreive the instance of the
|
|
Packit Service |
e31359 |
\link CppUnit::TestFactoryRegistry TestFactoryRegistry \endlink:
|
|
Packit Service |
e31359 |
\code
|
|
Packit Service |
e31359 |
CppUnit::TestFactoryRegistry ®istry = CppUnit::TestFactoryRegistry::getRegistry();
|
|
Packit Service |
e31359 |
\endcode
|
|
Packit Service |
e31359 |
Then, we obtain and add a new \link CppUnit::TestSuite TestSuite \endlink created
|
|
Packit Service |
e31359 |
by the \link CppUnit::TestFactoryRegistry TestFactoryRegistry \endlink that
|
|
Packit Service |
e31359 |
contains all the test suite registered using CPPUNIT_TEST_SUITE_REGISTRATION().
|
|
Packit Service |
e31359 |
\code
|
|
Packit Service |
e31359 |
runner.addTest( registry.makeTest() );
|
|
Packit Service |
e31359 |
runner.run();
|
|
Packit Service |
e31359 |
return 0;
|
|
Packit Service |
e31359 |
}
|
|
Packit Service |
e31359 |
\endcode
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
\section post_build_check Post-build check
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
Well, now that we have our unit tests running, how about integrating unit
|
|
Packit Service |
e31359 |
testing to our build process ?
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
To do that, the application must returns a value different than 0 to indicate that
|
|
Packit Service |
e31359 |
there was an error.
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
\link CppUnit::TextUi::TestRunner::run() TestRunner::run() \endlink returns
|
|
Packit Service |
e31359 |
a boolean indicating if the run was successful.
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
Updating our main programm, we obtain:
|
|
Packit Service |
e31359 |
\code
|
|
Packit Service |
e31359 |
#include <cppunit/extensions/TestFactoryRegistry.h>
|
|
Packit Service |
e31359 |
#include <cppunit/ui/text/TestRunner.h>
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
int main( int argc, char **argv)
|
|
Packit Service |
e31359 |
{
|
|
Packit Service |
e31359 |
CppUnit::TextUi::TestRunner runner;
|
|
Packit Service |
e31359 |
CppUnit::TestFactoryRegistry ®istry = CppUnit::TestFactoryRegistry::getRegistry();
|
|
Packit Service |
e31359 |
runner.addTest( registry.makeTest() );
|
|
Packit Service |
e31359 |
bool wasSuccessful = runner.run( "", false );
|
|
Packit Service |
e31359 |
return !wasSuccessful;
|
|
Packit Service |
e31359 |
}
|
|
Packit Service |
e31359 |
\endcode
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
Now, you need to run your application after compilation.
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
With Visual C++, this is done in Project Settings/Post-Build step,
|
|
Packit Service |
e31359 |
by adding the following command: <tt>"$(TargetPath)"</tt>. It is expanded to
|
|
Packit Service |
e31359 |
the application executable path. Look up the project
|
|
Packit Service |
e31359 |
<tt>examples/cppunittest/CppUnitTestMain.dsp</tt> which
|
|
Packit Service |
e31359 |
use that technic.
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
|
|
Packit Service |
e31359 |
Original version by Michael Feathers.
|
|
Packit Service |
e31359 |
Doxygen conversion and update by Baptiste Lepilleur.
|
|
Packit Service |
e31359 |
*/
|