cmake应用:集成gtest进行单元测试,作为软件测试程序员应该怎样去规划自己的学习路线
先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新软件测试全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip1024b (备注软件测试)
正文
单元测试(Unit Testing),一般指对软件中的最小可测试单元进行检查和验证。最小可测试单元可以是指一个函数、一次调用过程、一个类等,不同的语言可能有不同的测试方法,暂时不必深究。
对于C/C++语言,单元测试一般是针对一个函数而言,单元测试的目的就是检测目标函数在所有可能的输入下,函数的执行过程和输出是否符合预期。可以说,单元测试是颗粒度最小的测试,对于软件开发而言,保证每个小的函数执行正确,才能保证利用这些小模块组合起来的系统能够正常工作。
和测试相关的另外一个重要概念是测试用例(Test Case)。百度百科给的定义是,测试用例是对一项特定的软件产品进行测试任务的描述,体现测试方案、方法、技术和策略,包括测试目标、测试环境、输入数据、测试步骤、预期结果、测试脚本等。
这个定义是比较广泛的,对于单元测试来说,就是测试在不同输入下,目标函数(模块)的预期执行过程和输出(返回值),每个不同的情形可以有一个或多个测试用例。编写测试用例需要尽量覆盖所有输入情况(尤其是边界值、特殊值、异常值)。比如下列函数:
int fibo(int i) {
if (i == 1 || i == 2) {
return 1;
}
return fibo(i - 1) + fibo(i - 2);
}
这个函数是为了实现斐波那契数列,所以输入可以分为几类,就可以覆盖所有情况:
-
小于等于0的整数
-
1和2
-
大于2的整数
对应地,可以设置以下测试用例:
-
输入0,期望值是0
-
输入1,期望值是1
-
输入2,期望值是1
-
输入3,期望值是2
-
输入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下):
-
libgtest.a
-
libgtest_main.a
-
libgmock.a
-
libgmock_main.a
其中libgtest.a提供单元测试相关的功能,libgtest_main.a提供单元测试的主入口,只有链接该库,测试用例就会编译成可执行文件;两个mock库也是类似的,主要提供数据库交互,网络连接等方面的模拟测试,这不是本文的重点。
此时就可以在链接其他目标时直接使用gtest的这4个编译目标(target)。
3 编写测试用例
接下来直接修改先前的两个测试用例源文件,实现相同的测试功能:
-
test/c/test_add.c
-
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中的断言分成两大类:
-
ASSERT_*系列:如果检测失败就直接退出当前函数
-
EXPECT_*系列:如果检测失败发出提示,并继续往下执行
gtest有很多类似的宏用来判断数值的关系、判断条件的真假、判断字符串的关系。 对于条件判断可以使用:
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注软件测试)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
。 对于条件判断可以使用:
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注软件测试)
[外链图片转存中…(img-IMSW2RAJ-1713293077092)]
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
更多推荐
所有评论(0)