GTest初体验 -- 遇到运行库libCMT冲突问题

原创
2015/09/10 18:18
阅读数 646

gtest是Google开源的C++单元测试框架,以前稍接触过boost::unittest和cmockery,这些框架的使用基本上是大同小异。由于项目涉及到gtest,那我就借此机会学习一下。

首先是从网站上下载最新的版本:http://code.google.com/p/googletest/downloads/list

之前在网上浏览了一些gtest相关的资料,据说是需要编译器支持C++ TR1。还好目前我用的两个环境ubuntu gcc 4.2.4和vs2010还不需要担心这个问题。

下了源码包之后,首先在vs2010下编译。在msvc目录下有个工程文件,打开一共有4个工程:gtest, gtest_main, gtest_prod_test和gtest_unittest。把debug和release都bulid一下,前两个生成了静态库.lib,后两个生产了可执行文件.exe。目前我只关心第一个gtest,企业的以后再慢慢研究。新建了一个作为单元测试的工程,把gtest的include路径、lib路径和文件都设好。

[cpp]  view plain copy
  1. #include <iostream>  
  2. #include "gtest/gtest.h"  
  3.   
  4. using namespace std;  
  5.   
  6. class MyClass  
  7. {  
  8. public:  
  9.     bool returnBoolean(){return true;}  
  10. };  
  11.   
  12. class MyClassTest:public testing::Test  
  13. {  
  14. public:  
  15.     virtual void SetUp()  
  16.     {  
  17.   
  18.     }  
  19.       
  20.     virtual void TearDown()  
  21.     {  
  22.           
  23.     }  
  24.   
  25.     MyClass m_MyClass;  
  26. };  
  27.   
  28. TEST_F(MyClassTest, returnBoolean_1)  
  29. {  
  30.     bool ret;  
  31.   
  32.     ret = m_MyClass.returnBoolean();  
  33.   
  34.     EXPECT_EQ(true, ret);  
  35. }  
  36.   
  37.   
  38. //---------------------------------------------------------  
  39. int main(int argc, char* argv[])   
  40. {   
  41.     testing::InitGoogleTest(&argc,argv);   
  42.     RUN_ALL_TESTS();    
  43.     std::cin.get();   
  44.     return 0;   
  45. }   

第一次bulid出了一大堆错误...

[plain]  view plain copy
  1.   
[plain]  view plain copy
  1. ..省略n多行...  
  2. 1>LIBCMTD.lib(printf.obj) : error LNK2005: _printf already defined in MSVCRTD.lib(MSVCR100D.dll)  
  3. 1>LIBCMTD.lib(vprintf.obj) : error LNK2005: _vprintf already defined in MSVCRTD.lib(MSVCR100D.dll)  
  4. 1>LINK : warning LNK4098: defaultlib 'MSVCRTD' conflicts with use of other libs; use /NODEFAULTLIB:library  

提示是符号重复定义,库冲突了。加上链接参数/NODEFAULTLIB:libCMTD,再bulid,还是一大堆类似的错误,只libcmtd.lib变成了libcpmtd。胡乱地加上/NODEFAULTLIB:libCPMTD,这回既有重复定义,又有未定义符号错误。试试反过来/NODEFAULTLIB:libMSVCRTD,还是不行。看来方向不对。

认真查资料得知,libCMTD.lib等库是vs默认选用的运行库。千辛万苦去对比gtest工程和我的工程的构建编译链接参数,终于发现C++代码生成里面runtime library项不一样:我的工程里用的是Multi-threaded Debug DLL (/MDd),而gtest用的是Multi-threaded (/MT)。于是尝试把我的工程参数也改过来,发现还是有错。经过几轮组合尝试,终于在/MTd和/NODEFAULTLIB:libCMTD参数下构建成功。后来,我试着把gtest的编译参数改成/MTd重新生成。这一回我的工程参数只要跟gtest保持一致用/MTd就构建成功了。运行看到RUN OK PASSED等字样,感觉这真是不容易啊....

到这里库冲突问题算是已经解决,但当中的原理还不是太清楚,以后研究...

最后小结gtest最基本的接口宏:

TEST(test_case_name, test_name) - 像定义一个函数那样建立一个测试用例,通常用于功能比较独立的测试

TEST_F(test_fixture, test_name) -  像定义一个函数那样建立一个测试夹具,需要一个夹具类协助,通常用于需要上下文的测试

RUN_ALL_TESTS() - 放在main函数里的东西,表示测试开始

EXPECT/ASSERT_*(expected, actual) - 测试检查点,EXPECT/ASSERT区别是前者失败会继续执行,后者将退出当前函数


展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
2 收藏
0
分享
返回顶部
顶部