CPPUnit User Guide

xiaoxiao2021-03-06  18

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 ("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

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

转载请注明原文地址:https://www.9cbs.com/read-41670.html

New Post(0)