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运行小析的更多相关文章

  1. Poco logger 日志使用小析

    Poco logger 日志使用小析 Poco logger 日志使用小析 日志 logger 库选择 Pocologger 架构简析 步骤一 生成消息 步骤二 写入logger 步骤三 导入chan ...

  2. JLink 软件复位、Halt及运行小工具

    调试硬件时常常需要复位目标芯片,每次断电上电太麻烦,又不喜欢总打开segger的命令行,于是就搞了这个小工具:   QT绿色软件,解压即可运行,打开JLinkRST.exe,点击Connect即可通过 ...

  3. hadoop之HDFS运行小观察

    hadoop 是当前很火的一个  大数据运行框架和平台, 对于这个神奇的大家伙我甚是搞不清楚,前段时间闲来无视便把 HADOOP 运行起来, 看着它的操作记录存储部分(操作日志), IMAGE 记录着 ...

  4. js回调函数,字符串,数组小析

    (一)回调函数:是指通过函数参数传递到其他代码的,某一块可执行代码的引用.这一设计允许了底层代码调用在高层定义的子程序.在抖动函数中,回调函数用于在实现一些功能之后采取的另外的措施,比如div,照片抖 ...

  5. ArcGIS Earth数据小析

    ArcGIS Earth,一款轻量级的三维地球应用.因为工作关系下载试用了半天,正好借这个机会简单研究一下ArcGIS Earth的大概思路,特别是地形数据的组成和影像数据的加载,在这总结整理一下.下 ...

  6. javaIO框架小析

    IO即数据读写.数据是应用的中心要素,而数据读写的能力和可扩展性是编程平台的基础支撑. 概念框架 方式: 字节流 Byte 和 字符流 Char 方向: 输入 Input 和 输出 Output : ...

  7. android GC内存回收小析

    由于时间问题,简单的谈谈自己的理解. 大家都知道,在android开发中,不需要自己去管理,有垃圾回收机制会自动帮我们去回收 没有被引用到的对象. 那垃圾回收机制到底是怎样的呢?下面列出本人的一些理解 ...

  8. vivado第一天从建立文件运行小程序开始

    今天,是第一天什么也处于懵懂的时候,首要的任务就是建立一个文件 首先打开vivado运行软件, 如图所示,选择第一个create new project 来新建文件 选择存储路径,一路向下 当选择芯片 ...

  9. ASP.NET 异步Web API + jQuery Ajax 文件上传代码小析

    该示例中实际上应用了 jquery ajax(web client) + async web api 双异步. jquery ajax post $.ajax({ type: "POST&q ...

随机推荐

  1. 基于jquery hover图片遮罩层滑动

    分享一款基于jquery hover图片遮罩层滑动.这是一款仿腾讯课堂的鼠标悬停经过图片遮罩透明层滑动效果.效果图如下: 在线预览   源码下载 实现的代码. html代码: <div clas ...

  2. Java springboot项目的jar发布方式

    做springboot的都知道,发布方式不是war发布了,是jar发布,启动jar就可以直接运行,并且环境都是集成的. 首先,先将项目打包成jar,这里假设你的eclipse已经安装了maven插件. ...

  3. 最美应用API接口分析

    最美应用API接口分析html, body {overflow-x: initial !important;}.CodeMirror { height: auto; } .CodeMirror-scr ...

  4. java中的设计模式一 装饰模式

    1.装饰模式(Decorator)的定义:又名包装(Wrapper)模式,装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 2.装饰模式以对客户端透明的方式动态的给一个对象附加上 ...

  5. [RTC]系统和RTC的时间保持一致

    hwclock输出的格式似乎是没有格式化的命令,所以只能修改date date "+%a %d %b %Y %I:%M:%S %p %Z"

  6. 【进阶修炼】——改善C#程序质量(9)

    140,使用默认的访问修饰符. 如果不加访问修饰符,成员变量的默认是private的,类默认是internal的.为了明确访问的权限,我倒是建议都加上访问修饰符,这省不了多少代码. 141,不知道该不 ...

  7. hbase源码系列(十一)Put、Delete在服务端是如何处理?

    在讲完之后HFile和HLog之后,今天我想分享是Put在Region Server经历些了什么?相信前面看了<HTable探秘>的朋友都会有印象,没看过的建议回去先看看,Put是通过Mu ...

  8. 阿里云免费SSL证书绑定+sever2012 IIS配置

    1.阿里云域名 2.点击证书 3.免费证书 4.下载证书 5.服务器-运行-mmc 进入制台程序 6.制台程序,选择菜单“文件"中的"添加/删除管理单元”-> “添加”,从“ ...

  9. PCL中分割方法的介绍(2)

    (2)关于上一篇博文中提到的欧几里德分割法称之为标准的距离分离,当然接下来介绍其他的与之相关的延伸出来的聚类的方法,我称之为条件欧几里德聚类法,(是我的个人理解),这个条件的设置是可以由我们自定义的, ...

  10. headfirst 07

    WEB 不论你在web上做什么, 都离不开请求和响应. web请求作为某个用户交互的结果由web浏览器发送到web服务器. 在web服务器上会生成web响应并发回到web浏览器.整个过程可以总结为5步 ...