gTest详解
1. 安装使用
1.1 安装
在https://code.google.com/p/googletest/ 下载源码
进入msvc, 注意编译方式, 如果是dll, 选择 gtest-md
编译生成lib文件, 然后引入.文件即可使用
1.2 使用
#include "gtest/gtest.h"
int _tmain(int argc, _TCHAR* argv[])
{
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
当然我们也可以输出到xml
int _tmain(int argc, _TCHAR* argv[])
{
testing::GTEST_FLAG(output) = "xml:";
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
2. 断言
断言的宏可以分为两类ASSERT系列和EXPECT系列。
TEST(StringCmpTest, Demo)
{
EXPECT_EQ(3, add(1, 2));
ASSERT_EQ(3, add(1, 2));
}
我们再来看下所支持的宏
- ASSERT_EQ
- ASSERT_NE
- ASSERT_LE
- ASSERT_LT
- ASSERT_GE
- ASSERT_GT
- EXPECT_EQ
- EXPECT_NE
- EXPECT_LE
- EXPECT_LT
- EXPECT_GE
- EXPECT_GT
- ASSERT_TRUE
- ASSERT_FALSE
- ASSERT_STREQ
- ASSERT_STRNE
- ASSERT_STRCASEEQ
- ASSERT_STRCASENE
- ASSERT_FLOAT_EQ
- ASSERT_DOUBLE_EQ
直接返回成功还是失败
- FAIL();
- ADD_FAILURE();
Predicate Assertions
在使用EXPECT_TRUE或ASSERT_TRUE时,有时希望能够输出更加详细的信息,比如检查一个函数的返回值TRUE还是FALSE时,希望能够输出传入的参数是什么,以便失败后好跟踪。因此提供了如下的断言:
- ASSERT_PRED1(pred1, val1);
- ASSERT_PRED2(pred2, val1, val2);
如果对这样的输出不满意的话,还可以自定义输出格式化
- ASSERT_PRED_FORMAT1(pred_format1, val1);`
- ASSERT_PRED_FORMAT2(pred_format2, val1, val2);
例子
如果我们有这样一个类Arithmetic
我们只需要新建一个ArithmeticUnit.cpp文件,然后写下如下代码:
#include "stdafx.h"
#include "Arithmetic.h"
#include "gtest/gtest.h"
TEST(Arithmetic, add){
Arithmetic arith;
int a(1), b(2);
EXPECT_EQ(3, arith.add(1, 2));
}
3. 深入解析gTest
首先从TEST宏入手, 我们看下宏的定义
//1
define TEST(test_case_name, test_name) GTEST_TEST(test_case_name, test_name)
//2
#define GTEST_TEST(test_case_name, test_name)\
GTEST_TEST_(test_case_name, test_name, \
::testing::Test, ::testing::internal::GetTestTypeId())
//3
#define GTEST_TEST_(test_case_name, test_name, parent_class, parent_id)\
class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\
public:\
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {}\
private:\
virtual void TestBody();\
static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_;\
GTEST_DISALLOW_COPY_AND_ASSIGN_(\
GTEST_TEST_CLASS_NAME_(test_case_name, test_name));\
....
所以
1. 最终展开的宏是继承自testing::Test类
2. 我们最终写的代码是放在TestBody()中的
3. 通过静态变量test_info_,调用MakeAndRegisterTestInfo对测试案例进行注册。
看下MakeAndRegisterTestInfo 是如何实现的
TestInfo* MakeAndRegisterTestInfo(
const char* test_case_name,
const char* name,
const char* type_param,
const char* value_param,
TypeId fixture_class_id,
SetUpTestCaseFunc set_up_tc,
TearDownTestCaseFunc tear_down_tc,
TestFactoryBase* factory) {
TestInfo* const test_info =
new TestInfo(test_case_name, name, type_param, value_param,
fixture_class_id, factory);
GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info);
return test_info;
}
TestInfo对象主要用于包含如下信息:
测试案例名称(testcase name)
测试名称(test name)
该案例是否需要执行
执行案例时,用于创建Test对象的函数指针
测试结果
我们还看到,TestInfo的构造函数中,非常重要的一个参数就是工厂对象
internal::TestFactoryBase* factory
它主要负责在运行测试案例时创建出Test对象
new ::testing::internal::TestFactoryImpl<\
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>)
我们再来看下 TestFactoryImpl 是如何实现的
template <class TestClass>
class TestFactoryImpl : public TestFactoryBase {
public:
virtual Test* CreateTest() { return new TestClass; }
};
我靠, 这也能算是工厂吗~
不过总之流程是, 我们要创建一个测试对象的时候,先调用factory的CreateTest()方法 创建TestInfo对象, 再通过 GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info);对TestInfo对象进行注册
UnitTest 是单例
UnitTestImpl 是实现
void AddTestInfo(Test::SetUpTestCaseFunc set_up_tc,
Test::TearDownTestCaseFunc tear_down_tc,
TestInfo * test_info) {
// 获取或创建了一个TestCase对象,并将testinfo添加到TestCase对象中。
GetTestCase(test_info->test_case_name(),
test_info->test_case_comment(),
set_up_tc,
tear_down_tc)->AddTestInfo(test_info);
}
这里TestCase对象就出来了
TEST宏中的两个参数,第一个参数testcase_name,就是TestCase对象的名称,第二个参数test_name就是Test对象的名称。而TestInfo包含了一个测试案例的一系列信息。
一个TestCase对象对应一个或多个TestInfo对象。
总结一下gtest里的几个关键的对象:
- UnitTest 单例,总管整个测试,包括测试环境信息,当前执行状态等等
- Test 我们自己编写的,或通过TEST,TEST_F等宏展开后的Test对象,管理着测试案例的前后事件,具体的执行代码TestBody。
- TestCase 测试案例对象,管理着基于TestCase的前后事件,管理内部多个TestInfo。
- TestInfo 管理着测试案例的基本信息,包括Test对象的创建方法。
一个简单的UML图如下

4. 撸一个山寨的
撸了一个山寨的,https://github.com/sld666666/TestUnit
gTest详解的更多相关文章
- 【转】gitlab CI流水线配置文件.gitlab-ci.yml详解
目录 GitLab CI流水线配置文件.gitlab-ci.yml详解 实验环境 GitLab CI介绍 .gitlab-ci.yml 配置参数 参数详解 script image services ...
- Linq之旅:Linq入门详解(Linq to Objects)
示例代码下载:Linq之旅:Linq入门详解(Linq to Objects) 本博文详细介绍 .NET 3.5 中引入的重要功能:Language Integrated Query(LINQ,语言集 ...
- 架构设计:远程调用服务架构设计及zookeeper技术详解(下篇)
一.下篇开头的废话 终于开写下篇了,这也是我写远程调用框架的第三篇文章,前两篇都被博客园作为[编辑推荐]的文章,很兴奋哦,嘿嘿~~~~,本人是个很臭美的人,一定得要截图为证: 今天是2014年的第一天 ...
- EntityFramework Core 1.1 Add、Attach、Update、Remove方法如何高效使用详解
前言 我比较喜欢安静,大概和我喜欢研究和琢磨技术原因相关吧,刚好到了元旦节,这几天可以好好学习下EF Core,同时在项目当中用到EF Core,借此机会给予比较深入的理解,这里我们只讲解和EF 6. ...
- Java 字符串格式化详解
Java 字符串格式化详解 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 文中如有纰漏,欢迎大家留言指出. 在 Java 的 String 类中,可以使用 format() 方法 ...
- Android Notification 详解(一)——基本操作
Android Notification 详解(一)--基本操作 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Notification 文中如有纰 ...
- Android Notification 详解——基本操作
Android Notification 详解 版权声明:本文为博主原创文章,未经博主允许不得转载. 前几天项目中有用到 Android 通知相关的内容,索性把 Android Notificatio ...
- Git初探--笔记整理和Git命令详解
几个重要的概念 首先先明确几个概念: WorkPlace : 工作区 Index: 暂存区 Repository: 本地仓库/版本库 Remote: 远程仓库 当在Remote(如Github)上面c ...
- Drawable实战解析:Android XML shape 标签使用详解(apk瘦身,减少内存好帮手)
Android XML shape 标签使用详解 一个android开发者肯定懂得使用 xml 定义一个 Drawable,比如定义一个 rect 或者 circle 作为一个 View 的背景. ...
随机推荐
- http状态码详解
1 网址协议不支持的协议. 2 检测器内部错误. 3 网址格式不正确. 5 无法连接到代理服务器. 6 无法连接到服务器或找不到域名. 7 连接服务器失败. 28 操作超时.可能原因:页面执行时间过长 ...
- Web.xml各版本模版
web.xml v2.3 web.xml v2.4 <?xml version="1.0" encoding="UTF-8"?> <web-a ...
- iostat命令学习
iostat命令主要用于监控linux系统下cup和磁盘IO的统计信息 可以通过iostat --help获得该命令的帮助信息 [oracle@std ~]$ iostat --help Usage: ...
- viewport
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale= ...
- Collection
集合(collection): 使用存储实例的变长的容 容器名 存储的元素类型 长度 数组 基本和引用 定长 集合 引用 ...
- pict(Pairwise Independent Combinatorial Testing)工具使用
PICT工具就是在微软公司内部使用的一款成对组合的命令行生成工具,现在已经对外提供,可以在互联网上下载到. 要把输入类型和其对应的参数输入到一个CSV格式(CSV: 以逗号分割的纯文本文件,不带有任何 ...
- http详解
mac地址是网卡出厂的时候给定的固定地址.ip是当前节点被分配的地址,mac和ip相互配对: ip间通信- http本身是无状态无连接的,因为有这样的特性才能让他适用于当今这么复杂的网络环境. 但是有 ...
- Tomcat与Jre绿色环境配置(生产环境)
Tomcat与Jre绿色环境配置(生产环境) 博客分类: Apache Java jreapachetomcat Tomcat运行时需要jre的支持,一般有两种方式,一种是用jdk带的jre,另一种 ...
- ExtJS笔记 Ext.data.Types
This is a static class containing the system-supplied data types which may be given to a Field. Type ...
- CocoaPods for Xcode
http://www.cnblogs.com/MrRed/p/5728933.html 非常方便的Xcode pods插件.可以很方便的在Xcode通过pods安装各种objective-c第三方库, ...