I. Preface
Golang unit test example
When designing a test case, you often need to consider passing different values to the tested function. Our previous practice is usually to write a general method and then compile it in the test case to call it. Even if a general method is used, such work is repetitive,golang unit test ProgramThe employees are too lazy to write less.CodeTo reuse code. Google programmers also considered this issue and provided a flexible parametric testing solution.
Ii. Old Solutions
For comparison,unit test golang I will mention the old solution. First, I post the isprime function (in example1.cc of gtest). This function is used to determine whether the input value is a prime number.
// Returns true iff N is a prime number.
Bool Isprime ( Int N)
{
// Trivial Case 1: small numbers
If (N <= 1 ) Return False ;
// trivial case 2: even numbers
If (n % 2 = 0 ) return n = 2 ;
//Now, we have that N is odd and N> = 3.
// Try to divide N by every odd number I, starting from 3
For ( Int I = 3 ; I + = 2 ){
// We only have to try I up to the squre root of N
If (I > N / I) Break ;
// Now, we have I <= N/I <n.
// If n is divisible by I, n is not prime.
If (N % I = 0 ) Return False ;
}
// N has no integer factor in the range (1, N), and thus is prime.
Return True ;
}
Unit testing in golang
If I want to write a test case that determines that the result is true, golang unit test best practices I need to input a series of values to let the FunctionIsprimeTo determine whether it is true (of course, the function is correct even if multiple values are passed in), so I need to write the following test case:
Unit test golang mock
Test (isprimetest, handletruereturn)
{
Expect_true (isprime ( 3 ));
Expect_true (isprime ( 5 ));
Expect_true (isprime ( 11 ));
Expect_true (isprime ( 23 ));
Expect_true (isprime ( 17 ));
}
Golang unit test database
We noticed that in this test case, I copied and pasted at least four times. What should I do if there are 50 or 100 parameters? At the same time, the above statement produces a test case with five checkpoints. If I want to convert five checks into five separate cases, it will be even more tiring.
Next, let's take a look at how gtest solves these problems for us.
Iii. parameterized solution
1. Tell gtest what your parameter type is
You must add a class to inheritTesting: testwithparam <t>Where T is the parameter type you need to parameterize. For example, in the above example, I Need To parameterize an int type parameter.
Class Isprimeparamtest: Public : Testing: testwithparam < Int >
{
};
2. Tell gtest what kind of test you will perform after obtaining the parameter value
Here, we will use a new macro (well, very excited): test_p. Google's answer to this "P" is very humorous, that is to say, you can understand it as "parameterized" or "pattern ". I prefer the "parameterized" explanation. In the test_p macro, use getparam () to obtain the specific value of the current parameter.
Test_p (isprimeparamtest, handletruereturn)
{
Int N = Getparam ();
Expect_true (isprime (n ));
}
Well, it's very concise!
3. Tell gtest what parameter range you want to test
Use the macro instantiate_test_case_p to tell gtest the range of parameters to be tested:
Instantiate_test_case_p (truereturn, isprimeparamtest, testing: values ( 3 , 5 , 11 , 23 , 17 ));
The first parameter is the prefix of the test case.
The second parameter is the name of the test case, which must be the same as the name of the previously defined parameterized class, for example:Isprimeparamtest
The third parameter can be understood as a parameter generator. The preceding example uses test: values to indicate parameters in parentheses. Google provides a series of functions generated by parameters:
Range (begin, end [, step]) |
The value range is begin ~ Between end, step size is step, excluding end |
Values (V1, V2,..., vn) |
V1, V2 to VN values |
Valuesin (container)AndValuesin (begin, end) |
From a C-type array, STL container, or iterator |
Bool () |
FetchValues: false and true |
Combine (G1, G2,..., GN) |
This is tough, it will be G1, G2 ,... GN, G1, G2 ,... GN itself is a parameter generator, which starts from G1, G2 ,.. in gn, a value is extracted and combined into a tuple as a parameter. Note: This function is only availableThe <tr1/tuple> header is valid in the system. Gtest automatically checks whether TR/tuple is supported. If your system doesIf gtest is wrong, you can reset the definition macro.Gtest_has_tr1_tuple = 1. |
Iv. Name of the parameterized test case
Because we use parameterized execution cases, I really want to know how each case name is named during the running case. I executed the above Code and output it as follows:
From the case name in the above box, we can see the naming rules of the case. This is very important for me who need to know the name of each case. The naming rules are roughly as follows:
Prefix/test_case_name.test.name/Index
V. Type parameterization
Gtest also provides solutions for dealing with different types of data and parameterized solutions. I personally think this solution is complicated. First, let's take a look at the type test and use the example in gtest.
First, define a template class that inherits testing: test:
Template < Typename t >
Class Footest: Public Testing: test {
Public :
Typedef STD: List < T > List;
Static T shared _;
T value _;
};
Then we define the specific data types to be tested. For example, the following defines the char, Int, and unsigned int to be tested:
Typedef testing: Types < Char , Int , Unsigned Int > Mytypes;
Typed_test_case (footest, mytypes );
A new macro is used to complete our test cases. When declaring the Data Type of the templateTypeparam
Typed_test (footest, doesblah ){
// Inside a test, refer to the special name typeparam to get the type
// Parameter. Since we are inside a derived class template, C ++ requires
// Us to visit the members of footest via 'eas '.
Typeparam n = This -> Value _;
//To visit static members of the fixture, add the 'testfixture ::'
//Prefix.
N+ =Testfixture: Shared _;
//To refer to typedefs In the fixture, add the 'typename testfixture ::'
//Prefix. The 'typename' is required to satisfy the compiler.
Typename testfixture: list values;
Values. push_back (N );
}
The above example also looks like type parameterization, but it is not flexible enough because you need to know the type list in advance. Gtest also provides a more flexible type parameterization method, allowing you to consider the list of types that need to be parameterized after completing the logic code of the test, and you can also use this list repeatedly. The following is an official example:
Template < Typename t >
Class Footest: Public Testing: test {
};
Typed_test_case_p (footest );
Next is a new macro.Typed_test_pClass to complete our test case:
Typed_test_p (footest, doesblah ){
// Inside a test, refer to typeparam to get the type parameter.
Typeparam n = 0 ;
}
Typed_test_p (footest, haspropertya ){}
Next, we need the above case to useRegister_typed_test_case_pMacro. The first parameter is the name of testcase, followed by the name of test.
Register_typed_test_case_p (footest, doesblah, haspropertya );
Next, specify the list of required types:
Typedef testing: Types < Char , Int , Unsigned Int > Mytypes;
Instantiate_typed_test_case_p (My, footest, mytypes );
This solution provides better flexibility than the previous one. Of course, the more flexible the framework is, the more complexity it will be.
Vi. Summary
Gtest provides us with the parameterized test function, which brings great convenience to our test. This allows us to write less and better code and complete multiple parameter types of test cases.
Series links:
1. Go to Google's open-source C ++ unit testing framework, one of the Google test series (gtest)-First known as gtest
2. Go to Google open-source C ++ unit test framework Google test series (gtest) 2-Assertions
3. Go to Google open-source C ++ unit test framework Google test series (gtest) 3-event mechanism
4. Go to Google's open-source C ++ unit test framework: four parameters of the Google test series (gtest)
5. go to Google open-source C ++ unit testing framework Google test series (gtest) 5-death Testing
6. go to Google open-source C ++ unit testing framework-Google test series (gtest)-running parameters
7. Go to Google open-source C ++ unit test framework Google test series (gtest) 7-in-depth analysis of gtest
8. go to Google open-source C ++ unit testing framework Google test series (gtest)-build your own unit testing framework