单元测试乱弹(二):gtest 初步
下载地址:http://code.google.com/p/googletest/downloads/list
现在的最新版本是1.6.
文档:http://code.google.com/p/googletest/w/list
下载,解压,过程略。
(1)编译gtest:
先看 README文件,基本上就知道怎么用了。linux下常见的三步曲(其实只有两步):
第一步:#./congure
第二步:#make
如果没问题的话,就OK了。
第三步:#make install
这里会提示:“'make install' is dangerous and not supported. Instead, see README for how to integrate Google Test into your build system.”
就是说在1.6版本的gtest中, make install是不适用的(据网上消息:之前各版本包括1.5都是可以使用make install的,未经验证)。所以这步就不需要了。
In the early days, we said that you could install compiled Google Test libraries on *nix systems using make install. Then every user of your machine can write tests without recompiling Google Test.
This seemed like a good idea, but it has a got-cha: every user needs to compile his tests using the same compiler flags used to compile the installed Google Test libraries; otherwise he may run into undefined behaviors (i.e. the tests can behave strangely and may even crash for no obvious reasons).
Why? Because C++ has this thing called the One-Definition Rule: if two C++ source files contain different definitions of the same class/function/variable, and you link them together, you violate the rule. The linker may or may not catch the error (in many cases it's not required by the C++ standard to catch the violation). If it doesn't, you get strange run-time behaviors that are unexpected and hard to debug.
If you compile Google Test and your test code using different compiler flags, they may see different definitions of the same class/function/variable (e.g. due to the use of #if in Google Test). Therefore, for your sanity, we recommend to avoid installing pre-compiled Google Test libraries. Instead, each project should compile Google Test itself such that it can be sure that the same flags are used for both Google Test and the tests.
大致意思就是说:之前的make install,会在机器上安装一份编译好的gtest库,以后测试时只需要链接该库就可以了(linux下的library大多数都采用这种方式)。这样虽然方便,但会带来一个问题:每个人使用gtest时,可能需要不同的编译选项,如果使用别人预先编译好的gtest库,可能会造成混乱。所以每个人在编译自己的测试工程时,需要自己编译自己需要的gtest库。因此现在并不提供make install.
那么,我们该怎么使用gtest呢?
(2)编译sample:
在gtest根目录下,有个make目录:
1 rao@server233:~/work/gtest-1.6.0/make$ make clean 2 rm -f sample1_unittest gtest.a gtest_main.a *.o 3 raozhengfeng@server233:~/work/gtest-1.6.0/make$ make 4 g++ -I../include -g -Wall -Wextra -c ../samples/sample1.cc 5 g++ -I../include -g -Wall -Wextra -c ../samples/sample1_unittest.cc 6 g++ -I../include -I.. -g -Wall -Wextra -c \ 7 ../src/gtest-all.cc 8 g++ -I../include -I.. -g -Wall -Wextra -c \ 9 ../src/gtest_main.cc 10 ar rv gtest_main.a gtest-all.o gtest_main.o 11 ar: creating gtest_main.a 12 a - gtest-all.o 13 a - gtest_main.o 14 g++ -I../include -g -Wall -Wextra -lpthread sample1.o sample1_unittest.o gtest_main.a -o sample1_unittest
如果没问题的话,它将编译gtest提供测示例:samples/sample1_unittest.cc,并生成测试程序:sample1_unittest
从编译输出看:sample1_unittest并没有使用静态库的方式进行连接,而是直接编译了gtest框架中的源文件:src/gtest_main.cc,src/gtest-all.cc。
这么看来:我们并不需要预先编译gtest框架,只需要在测试代码中引用gtest文件,然后修改Makefile即可(这其实是源码级别的引用)。
运行测试程序:
1 rao@server233:~/work/gtest-1.6.0/make$ ./sample1_unittest 2 Running main() from gtest_main.cc 3 [==========] Running 6 tests from 2 test cases. 4 [----------] Global test environment set-up. 5 [----------] 3 tests from FactorialTest 6 [ RUN ] FactorialTest.Negative 7 [ OK ] FactorialTest.Negative (0 ms) 8 [ RUN ] FactorialTest.Zero 9 [ OK ] FactorialTest.Zero (0 ms) 10 [ RUN ] FactorialTest.Positive 11 [ OK ] FactorialTest.Positive (0 ms) 12 [----------] 3 tests from FactorialTest (0 ms total) 13 14 [----------] 3 tests from IsPrimeTest 15 [ RUN ] IsPrimeTest.Negative 16 [ OK ] IsPrimeTest.Negative (0 ms) 17 [ RUN ] IsPrimeTest.Trivial 18 [ OK ] IsPrimeTest.Trivial (0 ms) 19 [ RUN ] IsPrimeTest.Positive 20 [ OK ] IsPrimeTest.Positive (0 ms) 21 [----------] 3 tests from IsPrimeTest (0 ms total) 22 23 [----------] Global test environment tear-down 24 [==========] 6 tests from 2 test cases ran. (1 ms total) 25 [ PASSED ] 6 tests.
测试示例运行成功了。接下来该研究怎么使用gtest来做单元测试了。