Convenient development tool CPPUNIT Quick User Guide
content:
Background basic principle CPPUnit principle manual use steps Commonly used in other practical questions Reference information about the author
In the Linux area:
Tutorial Tools & Product Codes & Component Articles
Li Qun (liqun@nsfocus.com) August 2003
This paper introduces the CPPUnit framework from the perspective of developers, and hopes to enable developers to master this technology as soon as possible. The following is discussed from the basic principles, CPPUNIT principles, manual use steps, usually used steps, other practical problems, etc. The following discussion is based on CPPUnit1.8.0.
0. Background cppunit is a LGPL-based open source project, the initial version transplantation from JUnit, is a very good open source test framework. CPPUNIT and JUnit are the same ideas comes from XProgramming. The main function is to manage unit tests and automate tests. This describes the powerful power of the test framework. Do you have the following questions during the development process? If the answer is affirmative, you should learn to use this technology:
The test code does not have a good maintenance, it needs to be overwritten again when you need to test; put too much energy, find the bug, and the new code still appears similar bug; write code, no bottom, is there a lot of bugs Waiting for yourself; newly modified code does not know if it affects other part of code; due to too much involve too much, it will not dare to modify the code; ... these issues will be involved. This powerful test framework is not much used in C language developers in China. From the perspective of developers, this paper introduces this framework, hoping to enable developers to master this technology as soon as possible as soon as possible. The following is discussed from the basic principles, CPPUNIT principles, manual use steps, usually used steps, other practical problems, etc. The following discussion is based on CPPUnit1.8.0. 1. Basic principles For the above questions, only the use of CPPUnit is not effective. The following is a brief description from the purpose of testing, test principles, etc., and then introduce specific use of CPPUnit. The first thing we have to write test code is to verify the correctness of the code or debug BUG. When writing test code, there is a targeted, for those who are easy to make, volatile written test code; without writing test code for each detail, of course, unless there is excessive or reliability requirements. The relationship between encoding and testing is inseparable. The recommended development process does not need to be tested after writing all or a lot of code, but is completed in part of the code, such as a function, followed by test code for verification. Then write some code, write the test. Each test is done over again. The advantage of doing this is that the code is finished, and the basic test is over again, and the heart is confident in the code. Moreover, the old code is constantly tested when writing new code, and the impact on other partial code can quickly discover, position. The process of continuously encoding the test is also the process of maintenance of test code so that the test code has always been effective. With the guarantee of each part of the test code, there is a mechanism for automatic testing, and there is nothing concerned about the previous code. In extreme programming (a software development ideology), even emphasize the test code first, then write code that meets the test code, and then complete the entire software. Based on the purposes, ideas, the following summary of the principles of unit testing during the usual development process:
Write the test code first, then write code that meets the test. After at least the completed part of the code, complete the corresponding test code; the test code does not need to overwrite all details, but there should be corresponding test cases for all major functions and possibly wrong places; discovery BUG, first write the corresponding test case , Then debug; constantly summarize the cause of BUG, write corresponding test cases for other code; each write completion code, run all previous test cases, verify the impact on the previous code, to eliminate this effect as soon as possible; continuous maintenance test code , Guarantee that the code changes through all the tests; there is a guide to the theory, the test behavior can be ruled. So how CPPUnit implements this test framework to help us manage test code and complete automatic testing? Let's take a look at the principles of CPPUnit. 2. CPPUnit Principle In CPPUnit, a test object of one or a set of test cases is called 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 of writing a TestCase include initialization of FixTure, and other initialization operations, such as generating a set of objects that are tested, initialization values; to operate FixTure according to a feature to be tested or a process; if the verification result is Correct; 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. 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 // TessRunner
CPPUnit :: qtui :: Testrunner // qt method Testrunner
CPPUnit :: mfcui: Testrunner in Testrunner // MFC
Here is an example of a text method Testrunner:
CPPUnit :: Textui :: Testrunner Runner;
CPPUnit :: testsuite * suite = new cppunit :: testsuite ();
// Add a test case
Suite-> AddTest (New CPPUnit :: TestCaller
"TestAdd", TestAdd);
/ / Specify running Testsuite
Runner.addtest (Suite);
// Start running, automatically display test progress and test results
Runner.run (", true); // Run All Tests and Wait
For the management of test results, display and other functions involve another type of object, mainly for internal to test results, progress management, and display of progress and results. Not introduced here. Below we sort out the ideas, combined with a simple example, string of the ideas mentioned above. 3. Manually use the steps first to specify the object fixture, and then determine the test case based on its function, process, and previous experience. This step is very important, directly related to the final effect of the test. Of course, the process of increasing the test case is a phased job. After starting the code, complete the test case of the function, to ensure its completion function; then combine the previous experience (such as boundary value test, path overlay test) Write test cases; finally, the test case is completed according to BUG when discovered related bugs. For example, test the integer addition, first define a new TestFixTure subclass, Mathtest, write test code for test cases. When you need to add a new test case, you only need to add a new test function to modify Setup and Teardown as needed. If you need to test new fixture, define a new TestFixTure subclass. Note: The following code is only used to represent the principle and cannot be compiled. /// mathtest.h
// a testfixture subclass.
// announce: Use as your owner risk.
// author: liqun (liqun@nsfocus.com)
// Data: 2003-7-5
#include "cppUnit / testfixture.h"
Class Mathtest: PUBLIC CPPUNIT :: TestFixTure {
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
// a testfixture subclass.
// announce: Use as your owner risk.
// author: liqun (liqun@nsfocus.com)
// Data: 2003-7-5
#include "mathtest.h"
#include "cppUnit / testassert.h"
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);
}
Then write the main function, organize the test case you need to test to TestSuite and run through Testruner. This part of the code will be changed much when adding a new test case. Just add new test cases to TestSuite.
/// main.cpp
// main file for cppunit test.
// announce: Use as your owner risk.
// author: liqun (liqun@nsfocus.com)
// Data: 2003-7-5
// Note: Cannot Compile, ONLY for Study. # Include "mathtest.h"
#include "cppunit / ui / text / Testrunner.h"
#include "cppunit / testcaller.h"
#include "cppunit / testsuite.h"
int main ()
{
CPPUnit :: Textui :: Testrunner Runner;
CPPUnit :: testsuite * suite = new cppunit :: testsuite ();
// Add a test case
Suite-> AddTest (New CPPUnit :: TestCaller
"TestAdd", TestAdd);
/ / Specify running Testsuite
Runner.addtest (Suite);
// Start running, automatically display test progress and test results
Runner.run (", true); // Run All Tests and Wait
}
4. Commonly used in the above way, if you want to add a new test case, you need to add each test case to TestSuite, and add a new TestFixTure to add all header files to main.cpp, more troublesome. 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:
/// mathtest.h
// a testfixture subclass.
// announce: Use as your owner risk.
// author: liqun (liqun@nsfocus.com)
// Data: 2003-7-5
#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
// a testfixture subclass.
// announce: Use as your owner risk.
// author: liqun (liqun@nsfocus.com)
// Data: 2003-7-5
#include "mathtest.h"
// 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
// main file for cppunit test.
// announce: Use as your owner risk.
// compile: g -lcppunit mathtest.cpp main.cpp
// Run: ./a.out
// Test: redhat 8.0 cppUnit1.8.0
// Author: liqun (a Little Modification. Liqun@nsfocus.com)
// Data: 2003-7-5
// 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");
// Add this TestSuite to Testrunner
Runner.addtest (registry.maketest ());
// run test
Runner.run ();
}
This adds new test cases only need to be declared at the beginning of the class definition. 5. Other actual problems typically contain test examples and test objects 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. 6. Reference information CPPUnit Home JUnitTest Infected: Programmers Love Writing Tests CPPUnit Cookbook Xprogramming Home Test Framework This article Download 7. About the author Li Qun, currently paying attention to the development, research of network security products; software development processes. You can contact him via liqun@nsfocus.com.
Page