C++测试利器--google test开源测试框架
资料
偶然发现了google的测试框架gtest,马上试了下,效果挺不错,特别是对于写c++的人来说,方便很多。以前自己写c++的模块,通常是写好了模块后再另外定义些函数,然后在函数里面写测试用例来测试模块,如果测试点比较多,光是定义测试函数都要花费不少时间。gtest相当于大大节省了这个过程,用起来非常简单,直接用宏来定义测试用例,并且有很多丰富的宏来辅助测试,例如断言、预测值、死亡测试等。
废话不多说,先上gtest的一些资料:
gtest的代码托管地址:https://github.com/google/googletest,用git clone下来就可以了。
使用gtest构建测试用例指导:https://github.com/google/googletest/tree/master/googletest
gtest英文文档:https://github.com/google/googletest/blob/master/googletest/docs/Documentation.md
gtest中文博客:玩转Google开源C++单元测试框架Google Test系列,这系列博客对gtest的具体使用讲解的非常详细。
gmock使用文档:https://github.com/google/googletest/blob/master/googlemock/docs/Documentation.md
gmock中文文档:Google Mock启蒙篇
gtest项目中包含了两个框架,一个gtest测试框架,一个是gmock框架。gtest类似于java里面的junit,用来做单元测试的;gmock主要是用来mock待测试模块依赖的一些对象,帮助你在测试中去除不必要的依赖,类似与java的jMock和EasyMock。
好了,接下来直接上例子吧(注:下面的例子都是在linux下编译运行的,如果要在Windows上,需要看看gtest的文档)。
gtest demo
clone下来gtest后,可以在googletest目录中找到make目录:

,make目录中的Makefile是gtest帮我们写好的一个使用gtest测试框架来测试模块的例子。我们只需要把这个文件拷贝到写测试模块代码的目录,再改下面几个地方就可以编译运行测试模块。
GTEST_DIR = .. #设置gtest的项目目录 USER_DIR = ../samples #设置测试代码所在的目录 CPPFLAGS += -isystem $(GTEST_DIR)/include #设置预处理器参数 CXXFLAGS += -g -Wall -Wextra -pthread #设置编译器参数 TESTS = sample1_unittest #设置编译目标 。。。 #下面的目标生成规则改成测试模块的 sample1.o : $(USER_DIR)/sample1.cc $(USER_DIR)/sample1.h $(GTEST_HEADERS) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/sample1.cc sample1_unittest.o : $(USER_DIR)/sample1_unittest.cc \ $(USER_DIR)/sample1.h $(GTEST_HEADERS) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/sample1_unittest.cc sample1_unittest : sample1.o sample1_unittest.o gtest_main.a $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@
上面都是make脚本的语法,不清楚的可以先Google下。好了,一起准备就绪后,来看看一个简单的例子。首先,先写个要测试的函数:
bool IsEven(int n) {
return (n % ) == ;
}
这是一个判断一个数是否为偶数的函数,是不是非常的简单~~下面我们就来编写一个简单的测试案例:
TEST(IsEvenTest, EqTest)
{
EXPECT_FALSE(IsEven());
EXPECT_TRUE(IsEven());
}
上面可以看到,编写一个测试案例是多么的简单。我们使用了TEST这个宏,它有两个参数,这两个参数的定义是:[TestSuiteName,TestCaseName],我的理解是TestSuiteName是对某个模块总案例名,TestCaseName是这个案例中某个case的名字。
对检查点的检查,我们上面使用到了EXPECT_FLASE和EXPECT_TRUE这两个宏,这两个宏主要分别用来判断函数返回值是否为false和true。Google还包装了一系列EXPECT_* 和ASSERT_*的宏,而EXPECT系列和ASSERT系列的区别是:
1. EXPECT_* 失败时,案例继续往下执行。
2. ASSERT_* 失败时,直接在当前函数中返回,当前函数中ASSERT_*后面的语句将不会执行。
至于其它具体宏的介绍,可以通过上面给出的链接来查看。
好了,一起都准备好了,运行的结果是所有的测试都通过。

如果我们把第一个EXPECT_FALSE改为EXPECT_TRUE的结果呢?答案是测试是失败的,而且会给出具体出错在文件中的哪一行,以及出错的原因。

这是个很简单的使用gtest的例子,虽然简单,但基本涵盖了使用gtest的流程,而且用这些基本的功能就能解决大部分问题了。至于gtes的一些高级功能,需要的时候可以查上面链接中的文档。
gmock demo
编译运行的方式和gtest类似,Makefile文件在googlemock目录中的make目录中,按前面类似的修改这个Makefile文件就行。现在要测试的模块如下:
void func(FooInterface *p)
{
p->DoThis();
}
这个模块依赖于实现了抽象类FooInterface的对象,FooInterface类定义如下:
class FooInterface {
public:
virtual ~FooInterface() {}
virtual void DoThis() = ;
};
现在我们需要mock这个抽象类,gmock通过下面的宏来实现:
class MockFoo : public FooInterface {
public:
MockFoo() {}
MOCK_METHOD0(DoThis, void());
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFoo);
};
MOCK_METHOD*是一个宏,用来mock父类中的虚函数,*表示函数需要接收*个参数。好了,现在有了Mock类,接下来我们开始写测试用例:
class MockFoo : public FooInterface {
public:
MockFoo() {}
MOCK_METHOD0(DoThis, void());
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFoo);
};
EXPECT_CALL宏表示将会在后面调用foo对象中的DoThis方法,并且调用次数为1。
一切都准备好了,现在直接make编译运行就可以了,运行结果为:

如果我们把最后的delete foo去掉会怎么样?

结果就是gmock会报错提示内存泄露了,但需要注意的是如果在函数func里面里面发生了内存泄露,gmock是检查不出来的。
最后如果我们把Times中预计的DoThis方法运行次数改为2,结果会怎样?

结果这个case运行会失败,预计的次数和实际调用次数不符合。
总结
上面两个demo也只是个简单的示例,它们仅仅展示了gtest和gmock的基本用法,这也是我们在实际测试时经常需要用到的东西,至于一些高级的功能,需要时可以参考官网文档。
C++测试利器--google test开源测试框架的更多相关文章
- 【通信框架】Google的开源通信框架protobuf概述
在阅读的过程中有不论什么问题,欢迎一起交流 邮箱:1494713801@qq.com QQ:1494713801 一.作用 protobuf(Protocol Buffers)是Google内部 ...
- Android开源测试框架学习
近期因工作需要,分析了一些Android的测试框架,在这也分享下整理完的资料. Android测试大致分三大块: 代码层测试 用户操作模拟,功能测试 安装部署及稳定性测试 代码层测试 对于一般java ...
- [转]Android开源测试框架学习
近期因工作需要,分析了一些Android的测试框架,在这也分享下整理完的资料. Android测试大致分三大块: 代码层测试 用户操作模拟,功能测试 安装部署及稳定性测试 代码层测试 对于一般java ...
- 可能是 Python 中最火的第三方开源测试框架 pytest
作者:HelloGitHub-Prodesire HelloGitHub 的<讲解开源项目>系列,项目地址:https://github.com/HelloGitHub-Team/Arti ...
- 开源you-get项目爬虫,以及基于python+selenium的自动测试利器
写在前面 爬虫和自动测试,对于python来说是最合适不过也是最擅长的. 开源的项目也很多,例如you-get项目https://github.com/soimort/you-get.盗链和爬虫神器. ...
- Python最火的第三方开源测试框架 ——pytest
一.介绍 本篇文章是介绍的是Python 世界中最火的第三方单元测试框架:pytest.它有如下主要特性: assert 断言失败时输出详细信息(再也不用去记忆 self.assert* 名称了) 自 ...
- Google的开源C++单元测试框架Google Test
玩转Google开源C++单元测试框架Google Test系列(gtest)(总) 前段时间学习和了解了下Google的开源C++单元测试框架Google Test,简称gtest,非常的不错. 我 ...
- Nodejs开源项目里怎么样写测试、CI和代码测试覆盖率
测试 目前主流的就bdd和tdd,自己查一下差异 推荐 mocha和tape 另外Jasmine也挺有名,angularjs用它,不过挺麻烦的,还有一个选择是qunit,最初是为jquery测试写的, ...
- 基于Java的四大开源测试工具
摘要:成功的应用程序离不开测试人员和QA团队反复地测试,应用程序在进行最后的部署之前,需要通过测试来确保它的负载管理能力以及在特殊情况下的工作条件和工作加载情况. %R[)vA t]N0 测试是应用程 ...
随机推荐
- 【NOIP2015】反思+题解
D1T1> 神奇的幻方 模拟即可. #include <cstdio> #include <cstring> #include <algorithm> #de ...
- [noip2013]货车运输(kruskal + 树上倍增)
描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物,司机们想知道每辆车在不超过车辆限重的情况下,最多能运多 ...
- python 错误AttributeError: 'module' object has no attribute 'AF_INET'
写了一个简单的python socket的程序.运行时,报错如下 原因:文件的命名与Python的function的命名冲突 修改名称后,发现还是无法运行,检查目录下面是否有 这样子的一个文件,删除即 ...
- Linux文件编辑之sed命令
文件编辑之sed命令 sed是一种流编辑器,它是文本处理中非常重要的工具,能够完美配合正则表达式使用,功能不同凡响.处理时,把当前处理的行存储在临时缓冲区中,称为模式空间 (pattern space ...
- HTML5学习笔记四:html5结构
一.大纲:大纲即文档中各内容区块的结构编排 1. 显示编排内容区块:使用section等元素创建文档结构,每个内容区块使用标题(h1~h6,hgroup); 2. 隐式编排内容区块:根据页面所书写的各 ...
- 关于金额,重量等浮点数的数据库字段设计(用Int,Long代替浮点数计算)
金额.重量.成绩等数据库字段推荐使用int或bigint类型. 通常我们数据库设计中金额,重量等涉及到小数位的字段会用float或decimal,mysql还可以用double,但往往每笔金额的计算我 ...
- 【Android】Activity
一.Android四大组件 Activity.Service.BroadCastReceiver.ContentProvider. 二.Activity的继承关系 三.建立.配置和使用Activity ...
- redis 2 字符串 和 hash
string是最简单的类型,一个key对应一个value,string类型是二进制安全的.redis的string可以包含任何数据,比如JPG图片或者序列化的对象 操作 set 设置key ...
- Unity3D中切换场景可能导致材质变暗的问题
Unity版本:5.1.1f1 做公司项目的时候,无意间发现了一个很奇葩的现象:场景A(纯UI,故没有光源)转场到场景B的时候,B中原有的光源似乎失效了,但在Hierarchy窗口中能够看到光源存在, ...
- 使用(Drawable)资源——图片资源
图片资源是最简单的Drawable资源,只要把*.png.*.jpg.*.gif等格式的图片放入/res/drawble-xxx目录下,Android SDK就会在编译应用中自动加载该图片,并在R资源 ...