bnv

转载 测试杂感:最好的代码覆盖率工具

上一篇 / 下一篇  2010-04-28 14:47:32 / 个人分类:性能测试

代码覆盖率(Code Coverage)是指测试执行覆盖代码的程度。在工业界,常用的代码覆盖率度量包括类覆盖、函数覆盖、语句块覆盖、分支覆盖等。通常,开发者需要使用某种测试工具去收集测试的代码覆盖率。例如,.NET开发者可以使用Visual Studio 2008去收集C#代码的函数覆盖和语句块覆盖。本文将介绍我心目中最好的代码覆盖率工具。

在2008年初,我接到一个测试任务,去测试一个Web服务。这个Web服务用C#实现,它接受Web服务调用,根据输入更新后台的数据库中的数据。这是一个小项目,核心逻辑大约在千行上下。我接手的时候,代码已经写完。开发者有简单的测试,他提供了5条端到端(end-to-end)测试用例供我参考。

当时,我最头痛的是完全不知道该Web服务的业务逻辑和实现逻辑。在仔细地阅读了规格说明和几封很长的讨论邮件之后,大致知晓了项目背景,但是仍旧不了解实现逻辑,也不知道什么行为是可以接受的、什么行为是错误的。由于开发者与我有16个小时的时差,不能随时和他联系,很多问题得不到及时的解答,测试很难展开。

为了有所突破,我只能阅读实现代码。我的方法是,在Visual Studio中单步执行开发者的测试用例,观察程序中变量值的变化和数据库中数据的改变。有了初步的认知,我开始增加测试用例。大部分测试用例都是一个模式:

  1. 恢复被测试Web服务的后台数据库到已知的初始状态。
  2. 调用Web服务。Web服务是无状态的,但是它会改变数据库中的数据。
  3. 对数据库中的数据进行一致性检查。我花了许多时间编写并增强检查代码,整个测试开发过程是渐进的。
  4. 执行当前测试所特有的检查。

设计完一个测试用例,我就在Visual Studio中单步执行它,从而更深入地了解实现逻辑。在阅读、执行代码的过程中,会发现潜在的问题。这时,我会增加一个测试用例去“证明”这个问题可以导致产品的失败。随着测试用例越来越多,我对代码的理解也越深,发现的缺陷也越多。后来,缺陷不那么好找了,我就仔细地读代码,特别是那些没有被测试覆盖过的代码。然后,便增加测试用例去尽可能地提高测用例的覆盖率。一方面,测试用例要尽可能地覆盖所有的代码块;另一方面,测试用例要覆盖所有主要的数据状态和我觉得有风险的数据变更。

在项目结束的时候,我对测试的代码覆盖率很有自信。只有三个在catch语句中的代码块没有被覆盖,它们在产品环境中被执行的概率非常低。我仔细阅读过代码,它们即便被执行也不会导致危险。实际上,我比较担心的是测试没有覆盖一些复杂的数据转换。虽然我在不停地补充此类测试用例,但是这个项目的测试周期较短,测试用例能够覆盖的程序状态空间还是偏少。庆幸的是,产品上线后运行良好,没有发现问题。

回顾这个项目,我觉得有两点经验可以吸取。

第一,人的大脑才是最好的代码覆盖率工具。代码覆盖率工具能提供大量的信息。只有在充分理解代码与测试的前提下,这些信息才能得到有效的利用。这个项目的代码规模较少,因此我没有使用代码覆盖率工具。通过反复阅读代码、调试代码,我收集了代码覆盖率信息,并利用这些信息改进了测试。可以说,代码覆盖率是随着对代码不断的探索而自然提高的。对于大型项目,合理的利用代码覆盖率工具自然是大有裨益的。在这一过程中,阅读、理解、探索代码仍旧是指导测试的核心活动。

第二,代码覆盖率只提供了程序结构被覆盖的信息,测试者还需要关注程序状态是否被有效地覆盖。在本项目中,程序的状态可以视为数据库中数据值。Web服务能否完成很多时候取决于取决初始数据值是否有效、目标数据值是否可以接受。不同的数据对于相同的执行路径会产生完全不同的结果。如果仅仅关注程序结构,很可能会漏掉一些由状态引发的问题


TAG:

 

评分:0

我来说两句

Open Toolbar