下表是一个对三种流行 C++单元测试框架的简单比较,Gtest 虽然发展起来的较晚,但丰富功能简单易用,易学,加之移植性较好,是跨平台项目单元测试框架比较好的选择。
表 1.单元测试框架比较 测试框架支持特性GtestBoost TestCPPUnit可移植性 较好 好(依赖于 Boost 库) 较好
丰富的断言 优 优 一般
丰富的断言信息 优 良好 较差
自动检测和注册测试用例 优 良 一般
易于扩展断言 易于扩展 一般 一般
支持死亡和退出测试(Death 和 Exit) 支持 支持 不支持
支持参数化测试(Parameterized test) 支持 支持 不支持
支持 Scoped_Trace 支持 不支持 不支持
支持选择性执行测试用例 支持 支持 支持
丰富的测试报告形式(xml) 支持 支持 支持
支持测试用例分组 Suites 支持 支持 支持
开源 是 是 是
执行速度 快 快 快
基于接口的Mock测试 通过Gmock支持 不支持 不支持
易用性 优秀 较复杂 较好
支持类型化的参数化测试 支持 不直接支持 不直接支持
测试驱动开发-GTest 简介
Gtest 是基于 xUnit 的 C++单元测试框架,支持自动化案例自动发掘,丰富的断言功能,支持用户自定义断言,支持死亡测试和退出测试,还有异常测试控制,支持值类型和类型化的参数化测试,接口简单易用,对每个测试案例有执行时间的输出,可以帮助分析代码的执行效率,单一接口文件 gtest.h。
图 1 是 Console 模式输出用红和绿表示失败和成功的测试用例,看起来比较符合 TDD 的策略和定义
图 1.GTest 的案例测试结果输出Gtest 的断言有两种形式,致命性断言(Fatal Assertion)和非致命性断言(Nonfatal Assertion)。
除了基本的断言形式外,Gtest 还包括一些其他的高级断言形式,比如死亡断言,退出断言测试和异常断言等。
Gtest 还有其他的一些特性,比如类型参数化测试,值类型参数化的测试,测试用例分组,洗牌式测试等,可以参照附录中列出的 Gtest 的官网获取更多的信息。
在测试驱动软件开发的过程中,我们不可避免的要去依赖第三方系统,比如文件系统、第三方库、数据库访问,其他的在线数据的访问等,按照测试驱动开发的快速反馈的原则,如果在单元测试用例中去直接访问这些信息,势必在测试驱动开发过程中会依赖这些资源从而造成访问时间无法控制, 所以单元测试一般应该避免直接访问第三方系统,这就是 Mock 测试的主要目的,用模拟的接口去替换真实的接口,模拟出单元测试需要的第三方数据和接口进而隔离第三方的影响,专注于自己的逻辑实现。Gmock 就是这样一个 Mock 框架,它是类似于 jMock、EasyMock 和 Hamcres ,但是是 C++版本的 Mock 框架。 Gmock 是基于接口的 Mock 框架,在 C++中接口的定义是通过抽象函数和抽象类来实现的,这种要求势必会要求我们尽量遵循基于接口的编程原则,把交互界面上的操作抽象成接口,以便是接口可被模拟 Mock。可以在附录中列出的 Gmock 官网获取更多信息。