单元测试的规划

本文基于一个使用Pylons框架的项目经验,讨论了单元测试的粒度与覆盖度问题。作者提出,为了减少测试代码量,可以通过增大测试粒度来确保覆盖范围,但这会牺牲定位错误的能力。

令狐写了一篇《单元测试》,源于我们上周的一次关于测试的讨论。TR说到的原子性、独立性、正交性的确也都是值得讨论的问题。不过我比较关注的是粒度和覆盖度。

讨 论是缘起于我们几个最近在合作的一个基于Pylons开发的小项目。Pylons本身是一个基于MVC的WEB框架,我们的应用可以简单地分层为: Controller, Function, Model 这样三层。Model里都是表结构的定义,没有什么好测试的;Function部分是主要的功能实现部分,所以我们在这里使用了Python的 unittest框架进行测试;当然,Pylons为Controller的测试提供了一个基于nose的测试环境,不过我们没用——因为在我们的应用中 Controller只是作为View与Function之间的接口。

但是问题就在这里了,实际开发中发现,某人的Controller代码居然也有错误——具体是谁我就不说了。原因自然是因为我们省略了对Controller的测试,所以这里的错误就不能被及时发现,或者说这部分功能代码没有被测试所覆盖到。

令狐在文中说到的第三点——单元测试应该能保证每一个函数的可靠性——应该说是一个完备的测试所要做到的,但是实际上总会有一些取舍。这其中的原因除了一些特别简单而且基本不会修改的函数可以不必测试以外(这点也要小心,有时越是简单的函数越可能出错),另外一部分原因在于一些函数的依赖性,比如对数据库或网络这样的外部资源的依赖。

回到我们那个具体的项目上。

我们当初之所以只对Function部分进行测试,就是因为这部分被我们设计为最主要的功能实现部分,结果现在出现问题——未被测试所覆盖的部分出错了。

最圆满的解决办法就是再给Controller加一层测试,确保测试的完备。但这样的话就要多一些编写测试的工作了。当然,多写点测试也不是什么坏事,但问题在于我前面已经说了,Controller层很薄,没有多少代码,专门为它写一套测试似乎有点多余。

关于测试的量应该控制在多少,ajoo兄的观点很值得参考。如果测试代码的代码量与被测试代码差不多,那么这样的测试似乎就没有意义了。

好吧,剩下的问题就是:如果减少了测试的代码量,如何保证覆盖范围足够大?答案是把粒度放得粗一些。

以这个案例来说,我 的观点是:实现对Controller层的测试,而放弃对Function层的测试——因为Controller层调用了Function层所有功能,也 就是说,测试可以确保同时覆盖Controller层和Function层。但是代价是失去了测试的准确定位功能,一旦出现测试不通过的情况就无法判断问 题是出在Controller层还是出在Function层。不过幸好Controller层很薄。

当然,令狐是不赞成我这个观点的,所以他写了那么一篇长文章。

其实这样的事情我是干过的。前两年为某商业软件写过一个他们的专用协议所需的反弹端口代理程序,因为如前面所说,这个程序有对网络的外部依赖,所以精确的定点测试比较困难,最后我在开发的时候是用了最偷懒的办法,也就是最粗粒度的测试:

用DUnit写了一个独立的测试程序,在其中实现了两个Mock,分别模拟通讯的两端与代理程序之间用专用协议连接,只要这两个Mock之间通过代理的通讯是正确的,就返回测试通过。

最后我就是用这样的方法把那个程序开发完成的。当然,中间也少不了很多DEBUG LOG的分析处理工作。囧。

总的来说,还是不推荐将测试粒度放得太粗,因为这将失去单元测试的一个很大方面的作用,增加DEBUG的工作量。但是同样不应该将粒度做得太细,这样测试就没有意义了。

单元测试计划 版本:V1.3 文 档 编 号 保 密 等 级 作 者 最后修改日期 审 核 人 最后审批日期 批 准 人 最后批准日期 修订记录 日期 版本 修订说明 修订人 目 录 1 导言 2 1.1 目的 2 1.2 背景 2 1.3 范围 2 2 进入条件 2 3 退出条件 2 4 代码级别标准 2 5 代码分级清单 3 6 单元测试风险 3 7 单元测试策略 3 7.1 策略描述 3 7.2 类型 3 7.2.1 代码走查 3 7.2.2 功能测试 4 7.2.3 边界测试 4 7.2.4 覆盖率测试 4 7.2.5 内存使用测试 4 7.2.6 测试方式 4 7.3 测试用例估算 4 8 工具 5 9 进度及分工 5 10 交付物 5 导言 目的 【描述该代码走查及单元测试计划的目的。】 背景 【描述代码走查及单元测试计划的背景,活动目的。如无特殊背景信息,可裁剪。】 范围 【说明该代码走查及单元测试计划在整个项目周期的适用范围】 进入条件 【描述项活动的测试依据和满足该阶段测试进入的条件和约束。】 退出条件 【描述满足该阶段测试退出的条件,编写时特别要根据 《项目量化管理计划》列举一些量化的退出指标,例如 致命和严重级别的缺陷清除率达到 100%】 代码级别标准 【请参考组织级文档《代码分类级别指南》,中规定进行分类,质量经理可根据项目情况,对级别和通过标准做适当调整,将最后确定的通过标准记录在以下表格中】 级别 检查项 通过标准 A 代码编写格式检查 B 代码编写质量检查 C1 代码走查 C2 C3 D1 测试用例代码覆盖率检查 D2 D3 D4 E 内存泄漏检查 代码分级清单 【由架构师根据代码级别标准,划分】 模块 代码 A B C D E C1 C2 C3 D1 D2 D3 D4 √ √ √ √ √             单元测试风险 【此处描述测试任务可能遇到的风险,以及规避的方法】 # 风险描述 可能性 风险影响 责任人 规避方法 【高、中、低】 【高、中、低】 单元测试策略 策略描述 【此处描述根据项目的具体特征所确定的代码走查及单元测试的策略(如:代码走查在本项目重点关注的地方、测试可行性分析,测试方法确定,测试类型选择)】 类型 【此处描述单元测试选择的测试类型,一般建议有如下几种:】 代码走查 目标: 技术: 完成标准: 需考虑的特殊事项: 功能测试 测试目标: 技术: 完成标准: 需考虑的特殊事项: 边界测试 测试目标: 技术: 完成标准: 需考虑的特殊事项: 覆盖率测试 测试目标: 技术: 完成标准: 需考虑的特殊事项: 内存使用测试 测试目标: 技术: 完成标准: 需考虑的特殊事项: 测试方式 【说明手工测试的部分和自动测试的部分】 测试用例估算 【说明对需要开发的测试用例数目的估算】 模块 类数目 测试类型 测试用例数 工具 【本次测试将使用的工具】 用途 工具 厂商/自产 版本 测试管理 测试执行 缺陷报告 进度及分工  【根据测试的模块,分解任务,计划工作量、时间、人员;制订该计划的同时请参考中层计划等相关计划和估算文档;对于代码走查的人员安排一般要求架构师、高级工程师对工程师、助理工程师的代码进行走查,同时高级工程师、工程师 之间进行代码互查】 模块 任务 工作量 开始日期 人员 代码走查 用例设计 用例开发 用例执行 工作量合计 代码走查 用例设计 用例开发 用例执行 交付物 【描述单元测试需要交付的工作产品】 交付物名称 责任人 参与者 交付日期 测试计划 代码走查报告 测试用例 测试报告
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值