编写优美的gtest测试案例

上传人:xiao****1972 文档编号:84958740 上传时间:2019-03-06 格式:DOC 页数:3 大小:63.50KB
返回 下载 相关 举报
编写优美的gtest测试案例_第1页
第1页 / 共3页
编写优美的gtest测试案例_第2页
第2页 / 共3页
编写优美的gtest测试案例_第3页
第3页 / 共3页
亲,该文档总共3页,全部预览完了,如果喜欢就下载吧!
资源描述

《编写优美的gtest测试案例》由会员分享,可在线阅读,更多相关《编写优美的gtest测试案例(3页珍藏版)》请在金锄头文库上搜索。

1、编写优美的GTest测试案例 使用gtest也有很长一段时间了,这期间也积累了一些经验,所以分享一下。GTest为我们提供了便捷的测试框架,让我们只需要关注案例本身。如何在GTest框架下写出优美的测试案例,我觉得必须要做到:案例的层次结构一定要清晰 案例的检查点一定要明确 案例失败时一定要能精确的定位问题 案例执行结果一定要稳定 案例执行的时间一定不能太长 案例一定不能对测试环境造成破坏 案例一定独立,不能与其他案例有先后关系的依赖 案例的命名一定清晰,容易理解 案例的可维护性也是非常重要,如果做到上面的8点,自然也就做到了可维护性。下面来分享一下我对于上面8点的经验:1. 案例的层次结构一

2、定要清晰所谓层次结构,至少要让人一眼就能分辨出被测代码和测试代码。简单的说,就是知道你在测什么。由于是进行接口测试,我已经习惯了如下的案例层次:DataDefine我会将测试案例所需要的数据,以及数据之间的联系全部在预先定义好。测试数据与案例逻辑的分离,有利于维护和扩展测试案例。同时,GTest先天就支持测试数据参数化,为测试数据的分离提供了进一步的便捷。什么是测试数据参数化?就是你可以预先定义好一批各种各样的数据,而你只需要编写一个测试案例的逻辑代码,gtest会将定义好的数据逐个套入测试案例中进行执行。具体的做法请见:玩转Google开源C+单元测试框架Google Test系列(gtes

3、t)之四 - 参数化SUTSUT,即system under test,表明你的测试对象是什么,它可以是一个类(CUT),对象(OUT),函数(MUT),甚至可以是整个应用程序(AUT)。我单独将这个层次划分出来,主要有两个目的:明确的表示出你的测试对象是什么 为复杂调用对象包装简单调用接口 明确表示测试对象是什么,便于之后对测试案例的维护和对测试案例的理解。同时,对于一些被测对象,你想要调用它需要经过一系列烦琐的过程,这时,就需要将这一烦琐的调用过程隐藏起来,而只关注被测对象的输入和输出。TestCase测试工程中,必须非常明确的表示出哪些是测试案例,哪些是其他的辅助文件。通常,我们会在测试

4、案例的文件名加上Test前缀(或者后缀)。我建议,将所有的测试案例文件或代码放在最显眼的地方,让所有看到你的测试工程的人,第一眼看到的就是测试案例,这很重要。Checker对于一个复杂系统的接口测试,仅仅坚持输入和输出是远远不够的。比如测试一个写数据库的函数,函数的返回值告诉你数据已经成功写入是远远不够的,你必须亲身去数据库中查个究竟才行。因此,对于某一类的测试案例,我们可以抽象出一些通用的检查点代码。如果做到上面的分层,那么一个测试案例写出来的结构应该会是这个样子:TEST(TestFoo,JustDemo)GetTestData();/获取测试数据CallSUT();/调用被测方法Chec

5、kSomething();/检查点验证这样的测试案例,一目了然。2. 案例的检查点一定要明确一定要明确案例的检查点是什么,并且让检查点尽量集中。有一个不好的习惯就是核心的检查点在分布在多个函数中,需要不断的跳转才能了解到这个案例检查了些什么。好的做法应该是尽量让检查点集中,能够非常清晰的分辨出案例对被测代码做了哪些检查。所以,尽量让Gtest的ASSERT_和EXPECT_系列的宏放在明显和正确的地方。3. 案例失败时一定要能精确的定位问题测试案例失败时,我们通常手忙脚乱。如果一个测试案例Failed,却不能立即推断是被测代码的Bug的话,这个测试案例也有待改进。我们可以在一些复杂的检查点断言

6、中加入一些辅助信息,方便我们定位问题。比如下面这个测试案例:intn=-1;boolactualResult=Foo:Dosometing(n);ASSERT_TRUE(actualResult)如果测试案例失败了,会得到下面的信息:Valueof:actualResultActual:falseExpected:true这样的结果对于我们来说,几乎没有什么用。因为我们根本不知道actualResult是什么,以及在什么情况下才会出现非预期值。因此,在断言处多加入一些信息,将有助于定位问题:intn=-1;boolactualResult=Foo:Dosometing(n);ASSERT_TR

7、UE(actualResult)LCallFoo:Dosometing(n)whenn=10)break;:Sleep(200);tryTimes+;status=GetServiceStatus(xxx);ASSERT_EQ(Running,status)CheckthestatusafterStartService(xxx);5. 案例执行的时间一定不能太长我们应该尽量让案例能够快速的执行,一方面,我们可以通过优化我们的代码来减少运行时间,比如,减少对重复内容的读取。一方面,对于一些比较耗时的操作,比如文件系统,网络操作,我们可以使用Mock对象来替代真实的对象。使用GMock是一个不错的

8、选择。6. 案例一定不能对测试环境造成破坏有的案例需要在特定的环境下来能执行,因此会在案例的初始化时对环境进行一些修改。注意,不管对什么东西进行了修改,一定要保证在案例执行完成的TearDown中将这些环境都还原回来。否则有可能对后面的案例造成影响,或者出现一些莫名其妙的错误。7. 案例一定独立,不能与其他案例有先后关系的依赖任何一个案例都不依赖于其他测试案例,任何一个案例的执行结果都不应该影响到别的案例。任何一个案例都可以单独拿出去正确的执行。所以,不能寄希望于前一个案例所做的环境准备,因为这是不对的。8. 案例的命名一定清晰,容易理解案例的名字要规范,长不要紧,一定要清晰的表达测试案例的用途。比如,下面的测试案例名称都是不好的:TEST(TestFoo,Test)TEST(TestFoo,Normal)TEST(TestFoo,Alright)比如像下面的案例名称就会好一点:TEST(TestFoo,Return_True_When_ParameterN_Larger_Then_Zero)TEST(TestFoo,Return_False_When_ParameterN_Is_Zero)

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 大杂烩/其它

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号