Googletest is a framework used to write c ++ unit tests. It is cross-platform and can be used on Windows, Linux, Mac, and other operating systems. Next, I will explain how to use the latest version 1.6 gtest to write your own unit test.
This article includes the following parts: 1. Obtain and compile googletest (gtest); 2. How to compile unit test cases; 3. How to execute unit test. 4. How does Google test execute our unit test cases.
1. Obtain and compile gtest
Gtest tries to implement cross-platform. Theoretically, it should provide multiple Binary packages. But in fact, gtest only provides the source code and the compilation method of the corresponding platform. Why? Google's explanation is that when we compile and compile gtest, some unique projects may want to add a lot of flags during compilation to delegate the compilation process to users, it allows users to process data more flexibly. This is a free BSD permission.
Source code acquisition address: http://code.google.com/p/googletest/downloads/list
Currently, gtest provides version 1.6.0. Let's take a look at the differences with previous version 1.5.0:
Changes for 1.6.0:* New feature: ADD_FAILURE_AT() for reporting a test failure at the given source location -- useful for writing testing utilities.。。。 。。。* Bug fixes and implementation clean-ups.* Potentially incompatible changes: disables the harmful 'make install' command in autotools. |
That's the bottom line. Make install is disabled. Why? UNIX's habit of compiling methods:./configure; Make; make install failed. It can only be said that Google is quite a kind of tool, and it began to challenge users' habits.
So how to compile it?
Run the following two commands to import the gtest.zip package:
g++ -I./include -I./ -c ./src/gtest-all.ccar -rv libgtest.a gtest-all.o
Then, libgtest. A is generated. This is what we want. In the future, write your own unit test, and you need the include directory under the libgtest. A and gtest directories. Therefore, we need to copy the 1 directory to our project.
After compilation is complete, how can I verify whether it is successful? (Unfriendly !)
cd ${GTEST_DIR}/make make ./sample1_unittest
If you see:
Running main() from gtest_main.cc[==========] Running 6 tests from 2 test cases.[----------] Global test environment set-up.[----------] 3 tests from FactorialTest[ RUN ] FactorialTest.Negative[ OK ] FactorialTest.Negative (0 ms)[ RUN ] FactorialTest.Zero[ OK ] FactorialTest.Zero (0 ms)[ RUN ] FactorialTest.Positive[ OK ] FactorialTest.Positive (0 ms)[----------] 3 tests from FactorialTest (0 ms total)[----------] 3 tests from IsPrimeTest[ RUN ] IsPrimeTest.Negative[ OK ] IsPrimeTest.Negative (0 ms)[ RUN ] IsPrimeTest.Trivial[ OK ] IsPrimeTest.Trivial (0 ms)[ RUN ] IsPrimeTest.Positive[ OK ] IsPrimeTest.Positive (0 ms)[----------] 3 tests from IsPrimeTest (0 ms total)[----------] Global test environment tear-down[==========] 6 tests from 2 test cases ran. (0 ms total)[ PASSED ] 6 tests.
The compilation is successful.
2. How to compile unit test cases
For example. I wrote an open-address hash table with three main methods del/get/Add to be tested. During the test, it is natural that I only want to construct a hash table object and perform many different combinations of operations on it to verify whether the three methods are normal. Therefore, I will not use the test method provided by gtest, because multiple tests cannot share the same data, and there is also a process for initializing hash table objects. So I use test_f. Test_f is a macro. test_f (classname, casename) {} performs specific verification in the function body.
The above is the class diagram for executing the unit test. Then, I need to write a series of unit test cases to test this class. To use gtest, first declare a class that inherits from the test class in gtest:
The code is simple:
class CHashTableTest : public ::testing::Test {protected:CHashTableTest():ht(100){}virtual void SetUp() {key1 = "testkey1";key2 = "testkey2";}// virtual void TearDown() {}CHashTable ht;string key1;string key2;};
Then, start writing test cases. You can use the above class members directly in the use cases.
TEST_F(CHashTableTest, hashfunc){CHashElement he;ASSERT_NE(\ht.getHashKey((char*)key1.c_str(), key1.size(), 0),\ht.getHashKey((char*)key2.c_str(), key2.size(), 0));ASSERT_NE(\ht.getHashKey((char*)key1.c_str(), key1.size(), 0),\ht.getHashKey((char*)key1.c_str(), key1.size(), 1));ASSERT_EQ(\ht.getHashKey((char*)key1.c_str(), key1.size(), 0),\ht.getHashKey((char*)key1.c_str(), key1.size(), 0));}
Note that the test_f Macro will generate a class directly, which inherits from the chashtabletest class we wrote above.
Gtest provides assert _ and objective CT _ macros to determine whether binary, string, and other objects are equal, true, and false. The difference between the two macros is that assert _ will not be executed if it fails, while audit CT _ will continue.
3. How to perform a unit test
First, we need to have a main function. The function content is very simple:
#include "gtest/gtest.h"int main(int argc, char** argv) {testing::InitGoogleTest(&argc, argv);// Runs all tests using Google Test.return RUN_ALL_TESTS();}
Initgoogletest parses parameters. Run_all_tests executes all the test and test_f functions in the project as test cases.
During execution, assume that the compiled executable file is unittest, then directly execute./unittest to output the result to the screen, for example:
[==========] Running 4 tests from 1 test case.[----------] Global test environment set-up.[----------] 4 tests from CHashTableTest[ RUN ] CHashTableTest.hashfunc[ OK ] CHashTableTest.hashfunc (0 ms)[ RUN ] CHashTableTest.addget[ OK ] CHashTableTest.addget (0 ms)[ RUN ] CHashTableTest.add2gettestCHashTable.cpp:79: FailureValue of: getHe->m_pNext==NULL Actual: trueExpected: false[ FAILED ] CHashTableTest.add2get (1 ms)[ RUN ] CHashTableTest.delget[ OK ] CHashTableTest.delget (0 ms)[----------] 4 tests from CHashTableTest (1 ms total)[----------] Global test environment tear-down[==========] 4 tests from 1 test case ran. (1 ms total)[ PASSED ] 3 tests.[ FAILED ] 1 test, listed below:[ FAILED ] CHashTableTest.add2get
We can see that the incorrect case indicates the file and the number of lines.
If we need to output data to an XML file, execute./unittest -- gtest_output = XML, and the test_detail.xml file will be generated in the current directory. The content is as follows:
<?xml version="1.0" encoding="UTF-8"?><testsuites tests="3" failures="0" disabled="0" errors="0" time="0.001" name="AllTests"> <testsuite name="CHashTableTest" tests="3" failures="0" disabled="0" errors="0" time="0.001"> <testcase name="hashfunc" status="run" time="0.001" classname="CHashTableTest" /> <testcase name="addget" status="run" time="0" classname="CHashTableTest" /> <testcase name="delget" status="run" time="0" classname="CHashTableTest" /> </testsuite></testsuites>
In this case, a simple unit test is completed. Because it is too simple, you do not need to use Google mock to simulate some dependencies. In the future, I will write some complex gtest unit tests with Google mock.
The following describes the gtest workflow.
4. How does Google test execute our unit test cases?
Start with the main function.
Our main function executes the run_all_tests macro. What does this macro do?
#define RUN_ALL_TESTS()\ (::testing::UnitTest::GetInstance()->Run())} // namespace testing
Originally, the run method of the unittest static factory instance was called! In gtest, all test cases are instances of the test class! Therefore, the run method will execute all test instances to run all unit tests. Let's look at the class diagram:
Why is all unit test cases a test instance?
We have two methods to write test cases. One is the test_f macro I mentioned above. This requires that we define a subclass to inherit from the test class. In the test_f macro, a new class is defined to inherit from the subclass defined above (two-fold inheritance ).
The second type is the test macro, which does not require user code to define classes. However, in Google test, the test macro defines a subclass that inherits from the test class.
Therefore, the run method of unittest only needs to execute all test instances.
Each unit test case is an instance of the test class subclass. It is also associated with testresult, testcase, and testinfo to provide results.
Of course, there are also eventlisten classes to monitor the output of results and control the Test Progress.
The above is not detailed in depth, but it just helps you understand how some simple gtest macros and unit test cases are executed. Next, I will use gmock to go into the Google unit testing method.