[C++] gtest入门教程

gtest

文章目录

  • gtest
    • 前言
    • 使用
      • 头文件和库
      • 命令行选项
    • 测试
      • 普通测试
      • 自定义测试类
        • 类内共享对象
        • 全局共享对象
      • 自定义测试模板
        • 值测试模板 参数化测试
        • 类型测试模板
      • 自省/反射
    • 检查
      • 值检查
        • 数值
        • C字符串
        • 自定义值检查1 1型检查函数 简单函数检查
        • 自定义值检查2 2型检查函数
        • 自定义值检查3 3型检查函数
        • gmock扩展检查
      • 类型检查
        • 编译期类型检查
      • 程序流检查
        • 普通
        • 异常
        • 检查
        • 崩溃
    • 桩对象 (gmock)
    • 自定义对象的流输出
    • 测试流程监听器
      • UnitTest
      • TestSuite
      • TestInfo
      • TestPartResult
    • 记录
      • 输出文件
      • XML记录
      • JSON记录
      • 添加自定义记录
    • 调试
      • 检查失败时断点
      • 检查失败时抛出异常
      • 异常
    • 特殊测试
      • 测试筛选器
      • 测试禁用标记
      • 重复测试
      • 乱序测试
    • gtest缺陷解决方案
      • 语句块标记
      • 断言失败扩散
        • HasFatalFailure
        • ASSERT_NO_FATAL_FAILURE
        • 在监听器中抛出断言失败异常

前言

重写了部分名称. 并调整了部分内容的顺序, 并有所删减.

如下:

  • 测试类, 即派生于的自定义派生类的类
  • 测试分类名, 即未使用任何自定义测试类的测试的仅用于分类和筛选的名
  • 测试类名/分类名, 定义测试时所用的第一个参数的内容, 原名测试套件
  • 测试名, 定义测试时所用的第二个参数的内容
  • 崩溃测试, 原名死亡测试
  • 检查, 即ASSERT和EXPECT和统称
  • 断言, 即ASSERT
  • 期望, 即EXPECT
  • 检查函数, 原名谓词, 谓词函数
  • 失败, 即未通过,
  • 成功, 即通过.
  • n型检查函数, 原无此名, 因对函数签名有渐进性的要求, 为做区分而起
  • 值测试模板, 原名参数化测试, 由于实际意义类似于模板而改名以模板为名称后缀
  • 类型测试模板, 原名类型测试, 改名理由同上

注意, 每个测试既不是函数也不是类, 不应用测试函数等称呼. 而是专门用专有名词称呼.

使用

头文件和库

使用gtest需包含头文件 , 并链接库 和 .

编译库时注意到属性->代码生成设置运行库为和.

gtest开源地址为 github.com/google/googletest, 编译代码建议用Cmake生成VS项目, 然后用VS编译生成lib文件, 最后复制头文件和lib文件到项目里.注意编译时Release, Debug, Win32, x64的lib都不能错.

可用以下代码

快速添加要链接的lib文件.

命令行选项

测试

普通测试

使用测试分类名和测试名定义一个测试.

若编译器支持中文变量名, 分类名和测试名可使用中文.

然后使用下面套路化的main函数启动测试.

可在类中添加

声明一个测试为类的友元.

若无特殊需求, 可以略过以下部分内容, 直接转到 检查章. 使用普通测试和一些常用的检查即可快速开始做测试.

使用NuGet包管理器添加GoogleTestAdapter后, 可在测试->测试资源管理器处让VS自动管理gtest的所有测试.

自定义测试类

每个测试都将从测试类做派生, 并生成实例以进行测试.

使用TEST定义测试则默认从派生.

自定义测试类要求从派生.

从自定义测试类创建测试应使用TEST_F, 同时改分类名为类名, 例如下

测试中可用this访问当前测试的实例.

可在类中添加

声明一个自定义测试类的测试为类的友元.

从派生自定义测试类后, 有以下类函数可重载.

  • 在测试创建时被调用
  • 在测试结束时被调用
  • 在进程启动时调用一次
  • 在进程退出时调用一次

注意, 虽然各个测试的类都派生自一个测试类, 但由于是不同实例, 因此非静态数据皆不共享.

类内共享对象

同一个类内的测试间可以通过静态变量共享对象, 以避免被测对象的反复构造析构.

  1. 自定义测试类public继承
  2. 定义并实现
  3. 定义并实现
  4. 定义测试时用取代.

静态对象用 SetUpTestSuite 和 TearDownTestSuite 进行创建和销毁.

gtest将在所有测试开始前调用 SetUpTestSuite, 所有测试结束后调用 TearDownTestSuite.

注意!

  1. 只定义静态对象指针, 不要定义静态对象. 否则跨文件间的静态对象的初始化顺序不可控.
  2. 虽然同一个测试类的测试间不会并行进行, 但进行顺序不是固定的. 测试中不要修改共享对象. 若做更改也必须要在测试结束时撤销修改.

全局共享对象

可以给所有测试定义共享对象.

  1. 自定义类public继承 .
  2. 定义并实现 .
  3. 定义并实现
  4. 在 前用为本类生成一个实例, 然后用 注册为全局共享对象.

gtest将接管实例并在测试开始前依次调用 SetUp 并在测试结束时反序调用 TearDown 和 delete. 因此不用另行 delete.

自定义测试模板

值测试模板 参数化测试

参数化测试即定义一套测试模板, 并对测试模板输入不同的值作为模板参数以生成多个测试.

  1. 自定义测试类public继承
  2. 在函数外用 定义测试数据.
  3. 使用取代或定义测试模板.

gtest将以 数据注释 为测试名前缀, 测试数据序 为测试名后缀 通过测试模板生成大量测试.

即两个接口类 和 的组合.

下面是数据生成器概览:

生成器名 参数 生成数据
Range (b, e, s=1) 以s为步长生成[b, e)区间内的的数据
Values (v1, v2, …) 简单枚举数据v1, v2, …
ValuesIn (a) 枚举C数组a内的数据
ValuesIn /td> 枚举STL容器c内的数据
ValuesIn (b, e) 枚举迭代器b到e的数据
Bool () 枚举true和false
Combine (g1, g2, …) 枚举生成器g1, g2, …等的
所有数据的所有组合(笛卡尔积)
并用std::tuple捆绑输出

将测试类在头文件中声明后, INSTANTIATE_TEST_SUITE_P测试数据和TEST_P测试模板可以分在不同文件定义. 可用于制作测试数据接口.

类型测试模板

即定义一套测试模板, 输入不同的类型进行测试.

  1. 自定义测试类模板public继承. 模板应能接收一个类型.
  2. 用 生成待测类型组合类型
  3. 用将待测类型组合类型绑定到测试类
  4. 使用 取代 定义测试模板

自省/反射

使用以下代码获取当前测试的信息对象

测试外包括测试类的静态函数, 调用返回空指针.

详见监听器

检查

可在测试中使用检查. 检查包括断言与期望.

测试里若无检查失败则测试通过.

除个别检查外, 所有检查都带前缀, 可在下述两项中二选一.

  • ASSERT_ : 断言, 不通过检查则中断测试, 当在测试外使用时要求函数返回.
  • EXPECT_ : 期望, 不通过检查并不中断测试.

值检查

数值

后缀 参数 通过条件
TRUE /td> c == true
FALSE /td> c == false
EQ (a, b) a == b
NE (a, b) a != b
LT (a, b) a < b
LE (a, b) a <= b
GT (a, b) a > b
GE (a, b) a >= b
FLOAT_EQ (a, b) float型 a ≈ b
DOUBLE_EQ (a, b) double型 a ≈ b
NEAR (a, b, e) abs(a – b) <= e
HRESULT_SUCCEEDED (h) SUCCEEDED(h) == true
HRESULT_FAILED (h) FAILED(h) == true

浮点数的大小比较未直接提供, gtest提供了3型检查函数

做浮点数大小检查. 使用方法例如下

对HRESULT的检查失败时, gtest将调用FormatMessageA显示HRESULT的解释.

C字符串

后缀 参数 通过条件
STREQ (a, b) C字符串相等
STRNE (a, b) C字符串不相等
STRCASEEQ (a, b) C字符串忽略大小写相等
STRCASENE (a, b) C字符串忽略大小写不相等

自定义值检查1 1型检查函数 简单函数检查

本检查可以是检查函数, 也可以是检查值.

当函数为测试员提供时, 为检查值.

1型检查函数要求返回值能隐式转为bool.

后缀 参数 通过条件
PRED1 (f, v) bool(f(v)) == true
PRED2 (f, v, w) bool(f(v, w)) == true
PRED3 (f, v, w, x) bool(f(v, w, x)) == true
PRED4 (f, v, w, x, y) bool(f(v, w, x, y)) == true
PRED5 (f, v, w, x, y, z) bool(f(v, w, x, y, z)) == true

自定义值检查2 2型检查函数

  1. 定义返回值为 的检查函数.
  2. 在检查通过的地方返回 .
  3. 在检查不通过的地方返回 , 返回前可对其使用 输出注释.
  4. 现可使用 和 做自定义检查.

2型检查函数要求返回 .

例如下:

注释将加在检查失败时的非通过值后, 并括上括 .

自定义值检查3 3型检查函数

  1. 定义返回值为 的检查函数. 函数的每个接收值的形参都在函数前面添加一个接收生成值的表达式的字符串()的形参.
  2. 在检查通过的地方返回 .
  3. 在检查不通过的地方返回 , 返回前可对其使用 输出注释.
  4. 现可该检查函数f使用 和 做自定义检查.
后缀 参数 通过条件
PRED_FORMAT1 (f, v) 自定义
PRED_FORMAT2 (f, v, w) 自定义
PRED_FORMAT3 (f, v, w, x) 自定义
PRED_FORMAT4 (f, v, w, x, y) 自定义
PRED_FORMAT5 (f, v, w, x, y, z) 自定义

3型检查函数要求返回, 而且要接收2n个参数, 其中前n个为C字符串().

一个符合要求的3型检查函数的签名如下:

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2020年4月4日
下一篇 2020年4月5日

相关推荐