cmake应用:集成gtest进行单元测试_gtest 用途集成测试

if (i == 1 || i == 2) {

return 1;

}

return fibo(i - 1) + fibo(i - 2);

}


 这个函数是为了实现斐波那契数列,所以输入可以分为几类,就可以覆盖所有情况:


  1. 小于等于0的整数


  2. 1和2


  3. 大于2的整数


  对应地,可以设置以下测试用例:


  1. 输入0,期望值是0


  2. 输入1,期望值是1


  3. 输入2,期望值是1


  4. 输入3,期望值是2


  5. 输入4,期望值是3


  可以比较明显地发现,如果输入是小于等于0的整数,这个函数就一直递归下去了。这也是开发过程中需要注意的,代码(功能)的使用者并不一定会遵循常规的思维(斐波那契数列不可能输入负数),开发者只能相信自己的代码,不要对输入有任何假设。


  上述test case在cmake-template项目的test/c/test\_gtest\_demo.cc中有示例


二、gtest简介


  Google Test是Google开源的一个跨平台的C++单元测试框架,简称gtest,它提供了非常丰富的测试断言、判断宏,极大方便开发者编写测试用例的流程,也是很多开源项目使用的测试框架。


  在前面介绍CMake的测试功能时,每个单元测试都是一个可执行文件,实现了main函数,在CMakeLists.txt中使用add\_test命令来添加测试用例:


  enable\_testing()


  add\_executable(test\_add test/c/test\_add.c)


  add\_executable(test\_minus test/c/test\_minus.c)


  target\_link\_libraries(test\_add math)


  target\_link\_libraries(test\_minus math)


  add\_test(NAME test\_add COMMAND test\_add 10 24 34)


  add\_test(NAME test\_minus COMMAND test\_minus 40 96 -56)


  通过使用gtest可以简化这个流程,让开发者可以专注在测试用例的书写上,而不用手动编写大量的main函数,以及一些判断输出是否符合预期的附加代码。


三、集成gtest  
   1 将gtest源码加入项目


  gtest是一个开源的框架,代码位于github仓库:google/googletest,本文介绍直接将gtest加入到项目中,通过CMake编译使用。


  首先在项目根目录新建一个third\_party目录,下载源码的最新release版本,并解压:


   # mkdir third\_party


   # cd third\_party


   # wget https://codeload.github.com/google/googletest/zip/refs/tags/release-1.10.0


   # unzip googletest-release-1.10.0.zip


  2 将gtest添加为子模块


  修改项目根目录的CMakeLists.txt文件,使用上一篇文章介绍的命令add\_subdirectory,在开启单元测试时,添加gtest为子模块,并将对应头文件路径添加进来:


  enable\_testing()


  add\_subdirectory(third\_party/googletest-release-1.10.0)


  include\_directories(third\_party/googletest-release-1.10.0/googletest/include)


  此时执行命令:


   # cmake -B cmake-build


   # cmake --build cmake-build


  可以看到构建目录下多了一个目录cmake-build/third\_party/googletest-release-1.10.0,并且gtest编译生成了4个新的库文件(gtest子模块的编译目标,位于目录cmake-build/lib下):


  1. libgtest.a


  2. libgtest\_main.a


  3. libgmock.a


  4. libgmock\_main.a


  其中libgtest.a提供单元测试相关的功能,libgtest\_main.a提供单元测试的主入口,只有链接该库,测试用例就会编译成可执行文件;两个mock库也是类似的,主要提供数据库交互,网络连接等方面的模拟测试,这不是本文的重点。


  此时就可以在链接其他目标时直接使用gtest的这4个编译目标(target)。


  3 编写测试用例


  接下来直接修改先前的两个测试用例源文件,实现相同的测试功能:


  1. test/c/test\_add.c


  2. test/c/test\_minus.c


  因为使用的是C++测试框架,所以上述两个源文件修改为.cc后缀。


  在源文件中include头文件gtest/gtest.h,使用gtest测试用例定义宏来定义测试用例:


  TEST(test\_case\_name, test\_name) {}


  一个test\_case\_name下面可以包含多个不同(test\_name)的测试。


  test/c/test\_add.cc内容为:


  #include "gtest/gtest.h"


  #include "math/add.h"


  TEST(TestAddInt, test\_add\_int\_1) {


    int res = add\_int(10, 24);


    EXPECT\_EQ(res, 34);


  }


  test/c/test\_minus.cc内容为:


  #include "gtest/gtest.h"


  #include "math/minus.h"


  TEST(TestMinusInt, test\_minus\_int\_1) {


    int res = minus\_int(40, 96);


    EXPECT\_EQ(res, -56);


  }


  显而易见,测试用例的代码量比之前少了很多,而且更加可读,更加专业。


  这里使用了一个判断值相等的断言EXPECT\_EQ,gtest中的断言分成两大类:


  1. ASSERT\_\*系列:如果检测失败就直接退出当前函数


  2. EXPECT\_\*系列:如果检测失败发出提示,并继续往下执行


  gtest有很多类似的宏用来判断数值的关系、判断条件的真假、判断字符串的关系。 对于条件判断可以使用:


  ASSERT\_TRUE(condition);  // 判断条件是否为真


  ASSERT\_FALSE(condition); // 判断条件是否为假


  对于数值比较可以使用:


  ASSERT\_EQ(val1, val2); // 判断是否相等


  ASSERT\_NE(val1, val2); // 判断是否不相等


  ASSERT\_LT(val1, val2); // 判断是否小于


  ASSERT\_LE(val1, val2); // 判断是否小于等于


  ASSERT\_GT(val1, val2); // 判断是否大于


  ASSERT\_GE(val1, val2); // 判断是否大于等于


  对于字符串比较可以使用:


  ASSERT\_STREQ(str1,str2); // 判断字符串是否相等


  ASSERT\_STRNE(str1,str2); // 判断字符串是否不相等


  ASSERT\_STRCASEEQ(str1,str2); // 判断字符串是否相等,忽视大小写


  ASSERT\_STRCASENE(str1,str2); // 判断字符串是否不相等,忽视大小写


  4 添加测试用例


  书写好测试用例源文件后,需要修改项目根目录的CMakeLists.txt:


  enable\_testing()


  add\_subdirectory(third\_party/googletest-release-1.10.0)


  include\_directories(third\_party/googletest-release-1.10.0/googletest/include)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值