| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 开发测试 -> GTest 总结 -> 正文阅读 |
|
[开发测试]GTest 总结 |
Google C++单元测试框架(简称Gtest),可在多个平台上使用(包括Linux, Mac OS X, Windows, Cygwin和Symbian),它提供了丰富的断言、致命和非致命失败判断,能进行值参数化测试、类型参数化测试、“死亡测试”。 1断言一般的,要测试一个方法(函数)是否是正常执行的,可以提供一些输入数据,在调用这个方法(函数)后,得到输出数据,然后检查输出的数据是否与我们期望的结果是一致的,若一致,则说明这个方法的逻辑是正确的,否则,就有问题。 ?在对输出结果进行检查(check)时,Gtest为我提供了一系列的断言(assertion)来进行代码测试,这些宏有点类似于函数调用。当断言失败时Gtest将会打印出assertion时的源文件和出错行的位置,以及附加的失败信息。这些输出的附加信息用户可以直接通过“<<”在这些断言宏后面。 Gtest中,断言的宏可以理解为分为两类,一类是ASSERT系列,一类是EXPECT系列。 ASSERT_*?系列的断言(Fatal assertion),当检查点失败时,退出当前函数(注意:并非退出当前案例)。 EXPECT_*?系列的断言(Nonfatal assertion),当检查点失败时,继续执行下一个检查点(每一个断言表示一个测试点)。 通常情况应该首选使用EXPECT_,因为ASSERT_*在报告完错误后不会进行清理工作,有可能导致内存泄露问题。 1.1布尔型检查
1.2二值检查
一般来说二进制比较,都是对比其结构体所在内存的内容。C++大部分原生类型都是可以使用二进制对比的。但是对于自定义类型,我们就要定义一些操作符的行为,比如=、<等。 1.3字符串检查
*STREQ*和*STRNE*同时支持char*和wchar_t*类型的,*STRCASEEQ*和*STRCASENE*却只接收char* 1.4异常检查
1.5浮点检查
在对比数据方面,我们往往会讨论到浮点数的对比。因为在一些情况下,浮点数的计算精度将影响对比结果,所以这块都会单独拿出来说。GTest对于浮点数的对比也是单独的 1.6相近值检查
2 宏测试2.1 TEST宏 ???????TEST宏是一个很重要的宏,它构成一个测试特例,它的原型是: ?TEST宏的第一个参数是test_suite_name(测试套件名),第二个参数是test_name(测试特例名)。测试套件名和测试特例名(也叫测试名)的区别和联系: 测试套件(Test Case)是为某个特殊目标而编制的一组测试输入、执行条件以及预期结果,以便测试某个程序路径或核实是否满足某个特定需求,测试特例是测试套件下的一个(组)测试。 以上述代码为例,三段TEST宏构成的是一个测试套件——测试套件名是FactorialTest(阶乘方法检测,测试Factorial函数),该用例覆盖了三种测试特例——Negative、Zero和Positive——即检测输入参数是负数、零和正数这三种特例情况。 对于测试套件名和测试特例名,不能有下划线(_)。因为GTest源码中需要使用下划线把它们连接成一个独立的类名 这样也就要求,我们不能有相同的“测试套件名和特例名”的组合——否则类名重合。 测试套件名和测试特例名的分开,使得我们编写的测试代码有着更加清晰的结构——即有相关性也有独立性。相关性是通过相同的测试套件名联系的,而独立性通过不同的测试特例名体现的。 2.2 TEST_F 宏测试PositiveNum这个类。 使用TEST_F前需要创建一个固件类,继承于::testing::Test类。在类内部使用public或者protected描述其成员,为了保证实际执行的测试子类可以使用其成员变量。在构造函数或者继承于::testing::Test类中的SetUp方法中,可以实现我们需要构造的数据。在析构函数或者继承于::testing::Test类中的TearDown方法中,可以实现一些资源释放的代码。“构造函数/析构函数”和“SetUp/TearDown”的选择,对于什么时候选择哪对,没有统一的标准。一般来说就是构造/析构函数里忌讳做什么就不要在里面做,比如抛出异常等。 TEST_F宏和TEST宏的实现非常接近,只是TEST_F宏的封装更加开放一些,所以对TEST宏的功能多了一些扩展。他的原型是: 第一个参数为测试套件名(与创建的固件类名一致),第二个为测试名,可任意取。 ???? 第一个测试中,修改了pn1成员数据值为-2,测试结果为ok,紧接着第二个测试结果也是ok(如果测试一的修改会影响测试二,结果应为fail)。所有局部测试都是正确的,验证了固件类中数据的恒定性,每个测试特例都是要新建一个新的PositiveNumTest对象,并在该测试特例结束时销毁它,这样可以保证数据的干净。 TEST_F与TEST的区别是,TEST_F提供了一个初始化函数(SetUp)和一个清理函数(TearDown),在TEST_F中使用的变量可以在初始化函数SetUp中初始化,在TearDown中销毁,并且所有的TEST_F是互相独立的,都是在初始化以后的状态开始运行,一个TEST_F不会影响另一个TEST_F所使用的数据,多个测试场景需要相同数据配置的情况,用 TEST_F。 2.3 TEST_P宏在设计测试案例时,经常需要考虑给被测函数传入不同的值的情况。我们之前的做法通常是写一个通用方法,然后编写在测试案例调用它。即使使用了通用方法,这样的工作也是有很多重复性的。 测试IsPrime这个函数(判断输入值是否为质数)。 用TEST这个宏,需要编写如下的测试案例,每输入一个值就需要写一个测试点,这还只是在一个测试中,如果把每个测试点单独创建一个测试,工作量就更大。 ?使用TEST_P这个宏,对输入进行参数化,就简单很多。 创建一个参数化类IsPrimeParamTest。继承自TestWithParam这个模板类,TestWithParam又继承Test和WithParamInterface<T>。 WithParamInterface<T>这个模板类定义了ParamType,用于参数型别推导,提供GetParam()函数,用于TEST_P宏里的实现逻辑获取参数。 使用INSTANTIATE_TEST_CASE_P这宏来告诉gtest你要测试的参数范围: 第一个参数PARAM是测试案例的前缀,可以任意取。 第二个参数是测试案例的名称,需要和之前定义的参数化的类的名称相同,如:IsPrimeParamTest 第三个参数是可以理解为参数生成器,上面的例子使用test::Values表示使用括号内的参数。Google提供了一系列的参数生成的函数:
TEST_P中两个参数,第一个为测试套件名(与创建的测试类名一致),第二个为测试特例名称。 3. 预处理事件机制gtest 提供了多种预处理事件机制,非常方便我们在测试之前或之后做一些操作。 1. 全局的,所有测试执行前后。 2. TestSuite级别的,在某测试套件中第一个测试前,最后一个测试执行后。 3. TestCase级别的,每个测试前后。 3.1全局事件要实现全局事件,必须写一个类,继承testing::Environment类,实现里面的SetUp和TearDown方法。 1. SetUp()方法在所有案例执行前执行 2. TearDown()方法在所有案例执行后执行 还需要在main函数中通过调用testing::AddGlobalTestEnvironment这个函数将事件挂进来,也就是说,我们可以写很多个这样的类,然后将他们的事件都挂上去,AddGlobalTestEnvironment这个函数要放在RUN_ALL_TEST之前。 ? 3.2 TestSuites事件需要写一个类,继承testing::Test,然后实现两个静态方法 1. SetUpTestCase() 方法在第一个TestCase之前执行 2. TearDownTestCase() 方法在最后一个TestCase之后执行 ? 3.3?TestCase事件TestCase事件是挂在每个案例执行前后的,实现方式和Test'Suites的几乎一样,不过需要实现的是SetUp方法和TearDown方法: 1. SetUp()方法在每个TestCase之前执行 2. TearDown()方法在每个TestCase之后执行。 ? ? 4. 测试用例运行入口???? RUN_ALL_TESTS()这个宏,从名字上来看,就是运行所有的测试用例,这才是我们运行测试用例的真正入口。它的原型是: ? RUN_ALL_TESTS()是一个宏,将其实现为函数,在这里,调用了UnitTest单例的Run函数,看调用过程,可以看到,依次调用的过程是 1.UnitTest::Run() 2. UnitTestImpl::RunAllTests() 3. TestCase::Run() 4. TestInfo::Run() 5. Test::Run() 5. 参考文档 |
|
开发测试 最新文章 |
pytest系列——allure之生成测试报告(Wind |
某大厂软件测试岗一面笔试题+二面问答题面试 |
iperf 学习笔记 |
关于Python中使用selenium八大定位方法 |
【软件测试】为什么提升不了?8年测试总结再 |
软件测试复习 |
PHP笔记-Smarty模板引擎的使用 |
C++Test使用入门 |
【Java】单元测试 |
Net core 3.x 获取客户端地址 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/17 20:18:38- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |