C++ UT单元测试(UnitTest)GTest+GMock
由于在实习过程中被公司通知要准备去做ut测试了,我之前没有这方面的经验所以一直在csdn上找文章看,但一直没找到很好的文章,看了一整天我也想把我目前掌握出来的知识供后人参考
后来被通知由于环境没有搭建好我不用去做了,所以我并没有实战过,这只是我这天学习的总结经验,很多术语说的都不专业请见谅,可以结合别的文章一起看应该会有收获,由于公司电脑限制访问网站了,只能看csdn,其实b站上应该会有更详细的教程可以去那里看看,在文章的末尾我会附上几篇我觉得很好的贴子,大家可以参考一下!
一、测试框架
一个单元测试的测试框架有以下要求
1.独立,可重复
2.反应测试代码的结构,具有测试完备性(例如:如果要测试的函数是一个判断是否为质数的函数,就要分负数-1,-2,-3 特殊的正数0,1,2 以及一般的整数17,20 来测试)
3.测试失败的时候尽可能提供多个错误信息,一个测试能发现多个错误
4.只需关注测试本身以及自动跟踪测试
5.测试简洁高效
二、Google test
google提供了两个库方便进行单元测试,分别是gtest和gmock,这里的gmock也被称为打桩测试,gmock是在gtest上开发的,包含gtest
若想使用这两个库文件,需要引用相应的头文件,以gtest为例:gtest/gtest.h libgtest.a libgtest_main.a <-- 这个库文件能提供初始化,提供main函数,执行测试案例
三、google层次关系
一个单元测试(项目)由很多测试套件(函数)组成,测试套件由很多测试案例组成,测试案例由很多断言组成
在这里举一个例子,这是你要测试的函数
// Returns n! (the factorial of n). For negative n, n! is defined to be 1.
//
int Factorial(int n) {
int result = 1;
for (int i = 1; i <= n; i++) {
result *= i;
}
return result;
}
// Returns true iff n is a prime number.
bool IsPrime(int n) {
// Trivial case 1: small numbers
if (n <= 1) return false;
// Trivial case 2: even numbers
if (n % 2 == 0) return n == 2;
// Now, we have that n is odd and n >= 3.
// Try to divide n by every odd number i, starting from 3
for (int i = 3; ; i += 2) {
// We only have to try i up to the squre root of n
if (i > n / i) break;
// Now, we have i <= n/i < n.
// If n is divisible by i, n is not prime.
if (n % i == 0) return false;
}
// n has no integer factor in the range (1, n), and thus is prime.
return true;
}
这是测试代码
#include
#include "sample1.h"
#include
TEST(FactorialTest, Negative) {
// This test is named "Negative", and belongs to the "FactorialTest"
// test case.
EXPECT_EQ(1, Factorial(-5));
EXPECT_EQ(2, Factorial(-1)); //如果是ASSERT_EQ,后边的EXPECT_GT将不在执行;如果是EXPECT_EQ,后边的测试EXPECT_GT继续执行
EXPECT_GT(Factorial(-10), 0);
EXPECT_TRUE(2 == Factorial(-7));//这个错误失败信息打印的是true或false,不会打印值
ASSERT_EQ(3, Factorial(-1));
}
int main(int argc, char **argv) {
//printf("Running main() from gtest_main.cc
");
testing::InitGoogleTest(&argc,argv);
return RUN_ALL_TESTS();
}
其中FactorialTest就是测试套件 Negative是其中一个测试案例
四、断言
断言都是成对出现的,每个断言都支持输出流提供更详细的错误信息
EXPECT_EQ(2, Factorial(-1)); 左右两个值相等则true 不相等则为false
//因为负数的阶乘为1不等于2.如果是ASSERT_EQ,后边的EXPECT_GT将不在执行;如果是EXPECT_EQ,后边的测试EXPECT_GT继续执行
还有很多断言,这个遇到一个学一个就好了,这个不是很难理解
五、googletest具体特性
1.简单的函数和类的测试 用TEST(测试套件,测试案例)
2.如果上一段代码的输出要作为待测函数的输入,即测试代码对环境或者资源有依赖,则需要使用测试夹具TEST_F(测试夹具类名,测试案例名),测试夹具和测试套件是同等级的东西
注:测试夹具使用前需要继承一个类型 testing::Test,且开始前要调用(SetUp),结束调用(TearDown)
六、gtest事件机制
可以在单元测试,测试套件,测试案例前后埋点,断言返回回调函数
我个人的理解是:用gtest时间机制前后埋点,可以对new和delete进行计数,通过判断次数new是否等于delete判断是否内存泄露
七、goolemock打桩测试
场景:测试慢,依赖太多库,通过网络访问服务器,逻辑流程难描述边界事件,难观察交互的流程
1.使用一个类模拟其他复杂对象
2.核心思想①调用哪些接口②调用多少次③调用顺序④参数是什么⑤接口的返回值是什么
3.通用语法 EXCEPT_CALL(mock_object,method(matches))
.Times(cardinality) cardinality为调用次数
.WillOnce(Action) Action为接口的返回值
.WillRepeatedly(Action)
无WillOnce(Action)和WillRepeatedly(Action)则Times(1)
n个WillOnce(Action)无WillRepeatedly(Action)则Times(n)
n个WillOnce(Action)和一个WillRepeatedly(Action)则Times(AtLeast(n))
#include "stdafx.h"
using namespace seamless;
using namespace std;
using ::testing::Return;
int main(int argc, char** argv) {
//Since Google Mock depends on Google Test, InitGoogleMock() is also responsible for initializing Google Test.
//Therefore there's no need for calling testing::InitGoogleTest() separately.
::testing::InitGoogleMock(&argc, argv);
int n = 100;
string value = "Hello World!";
MockFoo mockFoo;
EXPECT_CALL(mockFoo, getArbitraryString())
.Times(1)
.WillOnce(Return(value));
string returnValue = mockFoo.getArbitraryString();
cout << "Returned Value: " << returnValue << endl;
//在这里Times(2)意思是调用两次,但是下边只调用了一次,所以会报出异常
EXPECT_CALL(mockFoo, getPosition())
.Times(2)
.WillRepeatedly(Return(n++));
int val = mockFoo.getPosition(); //100
cout << "Returned Value: " << val << endl;
//getPosition指定了调用两次,这里只调用了一次,所以运行结果显示出错
return EXIT_SUCCESS;
GoogleTest单元测试 - 随笔分类 - 超超boy - 博客园 (cnblogs.com)
https://www.cnblogs.com/jycboy/category/900460.html
这个博主写了很多篇就UT写了很多文章都是基于Google给的文档,不过我们公司电脑访问不了所以我到现在也没见过那个文档
单元测试(UT,C++版)经验总结(gtest+gmock)_willonce-CSDN博客
https://blog.csdn.net/weixin_63437585/article/details/144635777?ops_request_misc=elastic_search_misc&request_id=1e8513bc51043a9b9abf0617cc9f55eb&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~baidu_landing_v2~default-1-144635777-null-null.142^v102^pc_search_result_base2&utm_term=C%2B%2BUT&spm=1018.2226.3001.4187








