Introduction
In the Google C ++ unit testing framework (gtest) series tutorial 3 -- test fixture, this article describes how to use the test firmware as a test instance (tests) configure and initialize data. In addition to the data initialization method, gtest also provides a way to share data between test instances.
Share data between test instances of the same test case
To realize the independence between test instances, gtest provides a method to generate a new firmware test object for each test instance, this ensures that the execution of one test instance does not affect the execution of other instances. However, for the following situations:
- Initialization data involves memory application and other operations. Constructing an object for each test instance brings a large amount of overhead;
- If a data exists, it is used in each instance, but no value is changed for each instance;
There is no need to put the data into the test firmware object. In a C ++ class, how can we make the data independent of the object and accessible to the object?
That's right! The static member variable of the C ++ class is used. The specific definition method is as follows:
- In the firmware test, declare the data that needs to be shared between test instances as static;
- Setuptestcase () is used to initialize shared data. teardowntestcase () is used to clear shared data. The function types of these two functions are static void.
In the testProgramDuring execution, gtest calls setuptestcase () before the first test instance is run, and CALLS teardowntestcase () after the last test instance is run. During this period, the shared data defined for the test instance can be used.
Let's look at an instance that shares data between test instances:
Class Footest: Public : Testing: test {
Protected :
Static Void Setuptestcase (){
Shared_resource _ = New ...;
}
Static Void Teardowntestcase (){
Delete shared_resource _;
Shared_resource _ = NULL;
}
// You can define per-test set-up and tear-down logic as usual.
Virtual Void Setup (){...}
Virtual Void Teardown (){...}
// Some expensive resource shared by all tests.
Static T * shared_resource _;
};
T * footest: shared_resource _ = NULL;
Test_f (footest, test1 ){
... You can refer to shared_resource here...
}
Test_f (footest, Test2 ){
... You can refer to shared_resource here...
}
Since gtest does not necessarily execute test instances in the declared order, we still need to maintain independence of test instances to avoid the mutual dependency caused by misuse of shared data. In the test instance, do not change the value of shared data, or restore the value of shared data after the data value is changed or before execution.
Program-level data sharing
As described earlier, gtest provides data management methods at the tests and test case levels. In addition, gtest provides a shared data management method at the program level, allowing us to share data between test cases and test instances.
To implement program-level data sharing, first we need to define a class inherited from: Testing: environment, and write setup () and teardown () the function overwrites the corresponding virtual function in the parent class. The member variables in this class can be used as shared data:
ClassEnvironment {
Public:
Virtual~ Environment (){}
//Override this to define how to set up the environment.
Virtual VoidSetup (){}
//Override this to define how to tear down the environment.
Virtual VoidTeardown (){}
};
Second, call the following interface to "register" class objects:
Environment * addglobaltestenvironment (Environment * env );
Its parameter is the class Object Pointer before "Registration", and the returned value is the class object pointer after "Registration. Let's take a look at the example below:
Class Fooenvironment: Public Testing: Environment
{
Public :
Virtual Void Setup ()
{
Printf ( " Environment setup! \ N " );
A = 100 ;
}
Virtual Void Teardown ()
{
Printf ( " Environment teardown! \ N " );
}
Int A; // share data
};
Fooenvironment * foo_env; // Object Pointer Declaration
Test (firsttest, first) // access shared data and change its value
{
Printf ( " In the firsttest, foo_env-> P is % d \ n " , Foo_env-> );
Foo_env-> A ++;
}
Test (secondtest, second) // access Shared data
{
Printf ( " In the secondtest, foo_env-> P is % d \ n " , Foo_env-> );
}
Int Main ( Int Argc, Char * Argv [])
{
Foo_env = New Fooenvironment;
Testing: addglobaltestenvironment (foo_env); // register
Testing: initgoogletest (& argc, argv );
Return Run_all_tests ();
}
The above test cases firsttest and secondtest both access Shared data. As a demonstration, firsttest modifies the value of shared data. The execution result of the test program is as follows:
[=========] Running 2 Tests from 2 Test cases.
[----------] Global test environment Set -Up.
Environment setup!
[----------] 1 Test from firsttest
[Run] firsttest. First
In the firsttest, foo_env-> P is 100
[OK] firsttest. First ( 0 MS)
[----------] 1 Test from firsttest ( 0 MS total)
[----------] 1 Test from secondtest
[Run] secondtest. Second
In the secondtest, foo_env-> P is 101
[OK] secondtest. Second ( 0 MS)
[----------] 1 Test from secondtest ( 0 MS total)
[----------] Global test environment tear-down
Environment teardown!
[=========] 2 Tests from 2 Test Cases ran .( 0 MS total)
[Passed] 2 Tests.
Summary
In gtest, there are two ways to share data between test instances (except the global variables). One is to share data between test instances of the same test case, the other is to share data with all test instances in the program. Data sharing between test instances compromises the independence of execution between test instances. In my opinion, we should avoid using the data whenever possible.
Reference: googletest Project