CPPUnit User Guide
Test drive development principles:
Ø Write the test code first, then write code that meets the test. After the completion of the partial code, complete the corresponding test code;
Ø Test code does not need to overwrite all details, but there should be corresponding test cases on all major features and possible places;
Ø Discover BUG, first write the corresponding test case, then debug;
Ø Continuously summarize the cause of BUG, write corresponding test cases for other code;
Ø Each time you write complete code, run all previous test cases, verify the impact on the previous code, eliminate this effect as soon as possible;
Ø Continuously maintain the test code to ensure that all tests are passed after the code changes;
Ø Before the encoding: he can force you to analyze the needs.
Ø When encoding: He can keep you alert to Over Coding.
Ø When reconstructing: Make sure new designs can be compatible with older versions.
Ø When the team is developed: Make sure that your own unit is wrong.
CPPUnit principle
In CPPUnit, a test object for one or a set of test cases is referred to as fixture (facilities, below for easy understanding of the English name). FixTure is the target being tested, which may be an object or a set of related objects, or even a function.
With fix, you can write a test code for a function of this fixture, a possible error process, which is called TestCase (test usage) for a complete test of a certain aspect. The steps that usually write a TestCase include:
1. Initialize FixTure, and other initialization operations, such as: generating a set of test objects, initialization values;
2. Fix FixTure according to a feature to be tested or a process;
3. Whether the verification result is correct;
4. Clean up for FixTure and other resource releases.
Multiple test cases for FixTure, usually (1) (4) part of the code is similar, CPPUnit introduces SETUP and TEARDOWN virtual functions in many places. You can complete (1) initialization code in the setup function, and complete (4) code in the Teardown function. In the specific test case function, only the (2) (3) part of the code is required, and the runtime CPPUnit will automatically run the setup for each test case function, then run TEARDOWN, so that there is no crossover between the test cases.
Write TestCase must pay attention to the following points:
Ø Can be executed automatically, do not operate.
Ø Automatically return the test results.
Ø Absolute independence, can't have any contact with other TestCase. Even if you test the different functions of the same function, you need to separate. Every testcase can be said to be an island.
All test cases for FixTure can be packaged in a subclass of CPPUnit :: TestFixTure (naming convention is [ClassName] Test). Then define this fixture's setup and Teardown function, define a test function for each test case (naming convention is Testxxx). Here is a simple example: Class Mathtest: PUBLIC CPPUNIT :: TestFixTure {
protected:
INT M_VALUE1, M_VALUE2;
PUBLIC:
Mathtest () {}
// Initialization function
Void setup () {
M_Value1 = 2;
M_Value2 = 3;
}
// Test the test function of the addition
Void testAdd () {
// Step (2), operate FixTure
INT results = m_value1 m_value2;
// Step (3), whether the verification result is striving
CPPUNIT_ASSERT (Result == 5);
}
// Nothing clean job does not define TEARDOWN.
}
During the test function, the verification of the execution result is successful or failed to directly reflect the success and failure of this test case. CPPUnit provides a variety of ways to verify success failure:
CPPUNIT_ASSERT (CONDition) / / Confident Condition is true
CPPUNIT_ASSERT_MESSAGE (MESSAGE, CONDition) // When condition is fails to time, and print Message
CPPUNIT_FAIL (Message) // Current test failed, and prints Message
CPPUNIT_ASSERT_EQUAL (EXPECTED, ACTUAL) / / Great
CPPUNIT_ASSERT_EQUAL_MESSAGE (Message, Expected, Actual) / / Failed while printing Message
CPPUNIT_ASSERT_DOUBLES_EQUAL (Expected, Actual, Delta) // Failed when the difference between Expected and Actual is greater than Delta
To convert a test function of FixTure into a test case, you need to generate a cppunit :: testCaller object. When the test code that eventually runs the entire application, you may need to run multiple test functions to a FixTure at the same time, or even multiple fixtures test cases. The collection of this simultaneous test case is called TestSuite in CPPUnit. Testrunner runs test cases or TestSuite, and manages the life cycle of all test cases. At present, 3 Testrunner, including:
Ø CPPUNIT :: Textui :: Testrunner // Text method Testrunner
Ø CPPUNIT :: Qtui: Testrunner // qt method Testrunner
Ø CPPUNIT :: MFCUI: Testrunner // mfc method Testrunner
Below is an example of Testrunner:
CPPUnit :: Textui :: Testrunner Runner;
CPPUnit :: testsuite * suite = new cppunit :: testsuite ();
// Add a test case
Suite-> AddTest (New CPPUnit :: TestCaller
/ / Specify running Testsuite
Runner.addtest (Suite);
// Start running, automatically display test progress and test results
Runner.run (", true); // Run All Tests and Wait
Commonly used way
According to the above way, if you want to add a new test case, you need to add each test example to TestSuite, and add new TestFixTure to add all header files to main.cpp, trouble. To this end, CPPUnit provides CPPUnit :: TestSuiteBuilder, CPPUnit :: TestFactoryRegistry and a bunch of macros, which is used to easily register TestFixTure and test cases to TestSuite. Here is the usual way of use (attention red font):
/// mathtest.h
#include "cppunit / extensions / helpermacros.h"
Class Mathtest: PUBLIC CPPUNIT :: TestFixTure {
// Declare a TestSuite
CPPUNIT_TEST_SUITE (Mathtest);
// Add test cases to TestSuite, define new test cases to declare here.
CPPUNIT_TEST (TESTADD);
// TestSuite statement completed
CPPUNIT_TEST_SUITE_END ();
// The rest remain
protected:
INT M_VALUE1, M_VALUE2;
PUBLIC:
Mathtest () {}
// Initialization function
Void setup ();
// Cleanup function
Void Teardown ();
// Test the test function of the addition
Void TestAdd ();
/ / Add new test functions
}
/// mathtest.cpp
// Register this TestSuite to TestSuite "AllTest", if you do not define it will automatically define
// You can also cppUnit_test_suite_registration (Mathtest); register to a global unnamed TestSuite.
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION (Mathtest, "AllTest");
// below
Void Mathtest :: setup ()
{
M_Value1 = 2;
M_Value2 = 3;
}
Void Mathtest :: Teardown () {
}
Void Mathtest :: TestAdd () {
INT results = m_value1 m_value2;
CPPUNIT_ASSERT (Result == 5);
}
/// main.cpp
// No longer use the header file of all TestFixTure subclasses
#include
#include
// If you do not change TestSuite, this document does not need to be changed later.
int main ()
{
CPPUnit :: Textui :: Testrunner Runner;
// Get a specific TestSuite from the registered TestSuite, and there is no parameters to get the unnamed TestSuite.
CPPUnit :: TestFactoryRegistry & registry = cppunit :: testfactoryregistry :: getRegistry ("alltest"); // If you do not have a name, just call CPPUnit_test_suite_registration (Mathtest) in the Mathtest.cpp file; then you can write
CPPUnit :: TestFactoryRegistry & registry = cppunit :: testFactoryRegistry :: getRegistry ();
// Add this TestSuite to Testrunner
Runner.addtest (registry.maketest ());
// run test
Runner.run ();
}
/// mainAnother.cpp
Another way of writing. In fact, it is similar to that of the same size, but the generated object is TEST instead of registry.
Int main (int Argc, char * argv [])
{
// Get the top level suite from the registry
CPPUnit :: Test * Suite = cppunit :: testfactoryregistry :: getRegistry ();
// add the test to the list of test to run
CPPUnit :: Textui :: Testrunner Runner;
Runner.addtest (Suite);
// Change the default outputter to a compiler error Format Outputter
Runner.setputPutter (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;
}
This adds a new test case (TestFixTure) only needs to be declared at the beginning of the class definition.
Other actual problems
Typically contain test sample samples and test objects are in different projects. TestFixTure should be written in another project (preferably in different directories), and then the object being tested is included in the test item.
When testing a class or a function, this TestFixTure may reference other classes or other functions. In order to isolate other partial code, some pile programs should be temporarily defined in the source file, simulate these or functions. . These code can be valid in the test item through macro definitions, and is invalid in the project being tested.
Composition of CPPUnit
2 core part (CORE)
2.1 Basic Test Class
2.1.1
Test
2.1.2
TestFixTure
2.1.3
Testcase
2.1.4
Testsuite
2.2 Test Results Record
2.2.1
SynchronizedObject
2.2.2
Testlistener
2.2.3
TestResult
2.3 Error handling
2.3.1
Testfailure
2.3.2
Sourceline
2.3.3
EXCEPTION
2.3.4
Notequalexception
2.4 assertion
2.4.1 a
SSERTER
2.4.2
Testassert
3 Output section (OUTPUT)
3.1 Basic Parts
3.1.1
OUTPUTTER
3.1.2
TestResultCollector
3.2 derivative
3.2.1
TextOutputter
3.2.2
CompilerOutputter
3.2.3
XMLOUTPUTTER
4 accession part (Helper)
4.1 Creating a mechanism
4.1.1
TypeInfohelper
4.1.2
TestFactory
4.1.3
TestFactoryRegistry, NamedRegistries
4.1.4
TestsuiteFactory
4.1.5
TestSuiteBuilder
4.1.6
TestCaller
4.1.7 A
Utoregistersuite
4.2 Helpermacros
5 extended part (Extension)
5.1 TestDecorator
5.2 REPEATEDTEST
5.3 ORTHODOX
5.4 TestSetup
6 listener part
6.1 TestsucessListener
6.2 TEXTSTPROGRESSLISTENER
6.3 TEXTTSTRESULT
7 interface part (TextUi)
7.1 Testrunner
8 transplantation (Portability)
8.1 ostringstream
8.2 Other