gtest运行小析
Gtest是google推出的C++测试框架,本篇文档,从整体上对Gtest的运行过程中的关键路径进行分析和梳理。
分析入口
新建一个最简单的测试工程,取名为source_analyse_proj,建立一个简单的测试案例,为了便于分析,可以利用预编译处理器生成经过预编译的文件,来理解复杂宏。具体到VS环境中,进行如下设置:

生成项目,就可以找到对应的main.i预编译处理文件.如果需要生产obj文件,这里面的设置需要都修改为否
整体概览
从使用上,gtest可以看成是由各种不同的TEST宏组合成测试案例,再由RUN_ALL_TESTS()宏来执行各个不同的测试案例,下面来依次分析。
源码:

实际上定义了一个FooTest_HandleNoneZeroInput_Test的类:

可以看出,实际定义的类名称为“测试案例名称_测试名称_Test”,继承于 ::testing::Test类,里面有一个TestBody虚函数,可以猜想到测试框架在具体执行时,肯定是通过TestBody接口去执行各个不同测试案例中的测试函数。
每一个测试案例中都定义了一个静态成员指针,肯定是要在外部进行初始化操作的,这个操作留到下面去讲解。后面两句就是简单的拷贝构造函数和赋值构造函数,这里是为了不允许这两项操作,因此定义为private成员函数.
下面来讨论 test_info_成员,它的初始化时这样的:

利用::testing::internal的全局函数MakeAndRegisterTestInfo来实现初始化,因为它返回的是一个指针,所以可以想到这个函数应该是返回了一个new出来的指针.这里的最后一个输入参数为 new出来的模板实例, TestFactoryImpl提供了创建对应实例的接口,上面的TEST定义了一个类,在这里,生成这个类的模板实例,该类的实例生成需要等到后续执行过程中才会生成,每个测试实例的父类都是::testing::Test

MakeAndRegisterTestInfo的具体实现就下面两句:

这里面,要小析一下GetUnitTestImpl的实现,经过查阅,得知这里是一种将接口定义和细节实现分离的方式,获取主要整理细节代码如下:

UnitTest类中全部成员函数的实现,都是调用UnitTestImpl来实现的,在这里UnitTestImpl是实现,UnitTest是接口,两者之间相互隔离,接口隐藏底层实现细节
好了,我们回到正题,AddTestInfo从名字上面来看,意义应该是增加测试用例信息,这样的用例信息肯定有很多个,UnitTestImpl使用了

来保存每个TestCase信息,每一种TestCase下面可以含有多个测试子用例,所以在TestCase里面,用test_info_list_来保存同属于一个测试用例下面的测试子用例

这上面的一切操作,都是在初始化静态指针成员变量时完成的。
执行所有测试用例

测试框架启动代码,首选接管命令行输入,以便gtest可以通过额外的参数来控制测试流程。
然后调用RUN_ALL_TEST(),运行所有测试用例

这里通过UnitTest::Run进入,然后进入到UnitTestImpl::RunAllTests函数中,为这么这样设计,而不是一开始就进入RunAllTests函数中去呢?这里,gtest考虑到在测试程序执行中,可能会出现一些异常情况,而某些异常可能会导致整个测试进程退出,因此,在UnitTest::Run中,对各个适配平台的异常处理做了设置,确保这些异常不会终止程序,而是被准确记录下来。
测试案例执行流程,移除不相关代码

中间的循环依次执行TestInfo的Run函数,

这里面先会调用TestFactoryBase::CreateTest,这个是通用的虚函数,用于真实new出来测试用例的实例,每一个测试子案例都是派生自::testing::Test类,执行完对应的Run函数后,会通过Test::DeleteSelf_来释放掉对应的控件。Test类的Run函数简化后如下:

依次调用SetUp、TestBody和TearDown函数,其中,TestBody就是我们在TEST宏中真实定义的函数.这里,Gtest用到了特殊的方法来定位TestBody和实际代码入口,从预编译的结果上来看,应该是记录了TEST()宏后面测试语句的所在行号,在实际运行过程中,找到根据这个行号,找到对应的入口地址,然后去执行.具体原理,尚不清楚。
数据共享
全局测试数据共享,可以通过继承testing::Environment得到环境子类,在此子类中定义全局共享数据,在SetUp/TearDown虚函数中进行对应的初始化,启动时将此环境子类添加到全局环境中,就可在每个测试案例中使用。【这种方式,可能会破坏各个测试实例之间的独立性,不建议使用】
测试案例级别数据共享,可以通过继承testing::Test得到测试用例,在此子类中定义静态成员变量,在SetUpTestCase/TearDownTestCase虚函数中进行对应初始化,使用TEST_F来进行测试用例的声明,即可共享数据
参考链接:
http://www.cnblogs.com/jycboy/p/AdvancedGuide2.html
http://www.cnblogs.com/coderzh/archive/2009/04/06/1426755.html
gtest运行小析的更多相关文章
- Poco logger 日志使用小析
Poco logger 日志使用小析 Poco logger 日志使用小析 日志 logger 库选择 Pocologger 架构简析 步骤一 生成消息 步骤二 写入logger 步骤三 导入chan ...
- JLink 软件复位、Halt及运行小工具
调试硬件时常常需要复位目标芯片,每次断电上电太麻烦,又不喜欢总打开segger的命令行,于是就搞了这个小工具: QT绿色软件,解压即可运行,打开JLinkRST.exe,点击Connect即可通过 ...
- hadoop之HDFS运行小观察
hadoop 是当前很火的一个 大数据运行框架和平台, 对于这个神奇的大家伙我甚是搞不清楚,前段时间闲来无视便把 HADOOP 运行起来, 看着它的操作记录存储部分(操作日志), IMAGE 记录着 ...
- js回调函数,字符串,数组小析
(一)回调函数:是指通过函数参数传递到其他代码的,某一块可执行代码的引用.这一设计允许了底层代码调用在高层定义的子程序.在抖动函数中,回调函数用于在实现一些功能之后采取的另外的措施,比如div,照片抖 ...
- ArcGIS Earth数据小析
ArcGIS Earth,一款轻量级的三维地球应用.因为工作关系下载试用了半天,正好借这个机会简单研究一下ArcGIS Earth的大概思路,特别是地形数据的组成和影像数据的加载,在这总结整理一下.下 ...
- javaIO框架小析
IO即数据读写.数据是应用的中心要素,而数据读写的能力和可扩展性是编程平台的基础支撑. 概念框架 方式: 字节流 Byte 和 字符流 Char 方向: 输入 Input 和 输出 Output : ...
- android GC内存回收小析
由于时间问题,简单的谈谈自己的理解. 大家都知道,在android开发中,不需要自己去管理,有垃圾回收机制会自动帮我们去回收 没有被引用到的对象. 那垃圾回收机制到底是怎样的呢?下面列出本人的一些理解 ...
- vivado第一天从建立文件运行小程序开始
今天,是第一天什么也处于懵懂的时候,首要的任务就是建立一个文件 首先打开vivado运行软件, 如图所示,选择第一个create new project 来新建文件 选择存储路径,一路向下 当选择芯片 ...
- ASP.NET 异步Web API + jQuery Ajax 文件上传代码小析
该示例中实际上应用了 jquery ajax(web client) + async web api 双异步. jquery ajax post $.ajax({ type: "POST&q ...
随机推荐
- SQL 分页 SQL SERVER 2008
public IList<UserInfo> GetPageList(int pageSize, int pageIndex, out int totalItemCount) { var ...
- java 栈和队列的模拟--java
栈的定义:栈是一种特殊的表这种表只在表头进行插入和删除操作.因此,表头对于栈来说具有特殊的意义,称为栈顶.相应地,表尾称为栈底.不含任何元素的栈称为空栈. 栈的逻辑结构:假设一个栈S中的元素为an,a ...
- codeigniter2.2.5连接mssql2008Rc2
一.环境:php5.2.17(nts)+apache(Apache/2.2.22 (Win32))+server 2008 二.php框架:codeigniter2.2.5 三.配置php.ini # ...
- JAXP操作xml
DOM对象详解1.基本的DOM对象 DOM的基本对象有5个:Document,Node,NodeList,Element和Attr.下面就这些对象的功能和实现的方法作一个大致的介绍. Document ...
- PropertyChangeSupport
1 import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; /** * @author h ...
- NHibernate 知识点整理
1.实体bool类型属性与数据库映射.如实体中有bool属性IsDelete.配置如下 <property column="IsDelete" name="IsDe ...
- jQuery(七):节点操作
jQuery中节点操作主要分为以下几种: 查找节点. 创建节点. 插入节点. 替换节点. 复制节点. 删除节点. 一.查找节点 示例: <!DOCTYPE html> <html l ...
- 谷歌draco
前不久,谷歌开源的Draco关于点云的编码与压缩的源码,Draco 由谷歌 Chrome 媒体团队设计,旨在大幅加速 3D 数据的编码.传输和解码.因为研发团队的 Chrome 背景,这个开源算法的首 ...
- fastjson生成JSON字符串的时候出现$ref
fastjson生成JSON字符串的时候出现$ref 转载自:http://wuzhuti.cn/201426!826!05!130202.html 可以通过选项 DisableCircularRef ...
- maven启动项目时报错
java.lang.UnsupportedClassVersionError eclipse中使用maven插件的时候,运行run as maven build的时候报错 -Dmaven.multiM ...