代码覆盖率分析 [中文翻译0.1版]

发表于:2008-5-06 13:47

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:AlexanderIII    来源:51Testing论坛

译者按:
在文中被标识了[***]为译文不确定之处。
若有指正之处,请发邮件到cnalexanderiii_gmail_com请把”_”换成邮箱的特殊符号。

原文地址:
http://www.bullseye.com/coverage.html
作者:Steve Cornett
译者:AlexanderIII
联系方式:http://www.51testing.com/?61747cnalexanderiii_gmail_com

介绍

        代码覆盖率分析是在程序中寻找没有被用例测过的地方的流程;创建新的测试用例来增加覆盖率的流程;决定代码覆盖定量的量度方法,同时也是一种间接度量质量的方法的过程。

        它的另外一种使用方式是识别不会增加覆盖率的冗余用例,可由覆盖分析器来完成此过程。

        使用覆盖率分析,实际上是确保你的测试的质量,而不是确保实际产品的质量。一般情况下你也不会在对你发布产品上运行测试的时候使用覆盖分析器。覆盖分析通常需要访问到测试程序源代码,以及会经常需要用特殊的命令来重编译。

        本篇文章讨论了向测试计划增加覆盖分析时所需要考虑的详细内容。覆盖率分析有着它的优点和缺点。你需要选择采用哪些度量的方法。你要设定一个最低的覆盖率来决定什么时候停止分析覆盖。覆盖分析是一种测试的技术,但你不应该依赖于它的单独使用。

        覆盖分析有时候也叫“测试覆盖分析”, 这两种术语是同义的。在学术界里,术语“测试覆盖”使用得比较多,在测试业界里的话,使用得多的就是术语“代码覆盖”。同样的,覆盖分析器有时候也被叫做“覆盖监控器”。比较喜欢测试业界术语。

结构测试与功能测试

        代码覆盖分析是一种结构测试技术(AKA玻璃盒测试和白盒测试)。结构化测试是以源代码的意图表现为依据来比较被测程序行为的。这就与以需求规格为依据去比较被测程序行为的功能测试(AKA 黑盒测试)形成对比。结构化测试检查程序是如何工作的,以及代码结构和逻辑方面的潜在缺陷。功能测试是不管程序内部如何运作的,它只检查及关心程序实现了什么。

        结构化测试通常也叫做路径测试,那是因为你所创建的测试用例所经过的,就是程序路径的结构。要注意的是,千万不要把路径测试和路径覆盖度量搞混了,下面章节会解释。

        粗略的看上去,结构化测试似乎是不太稳妥的,它不能够找到被遗漏的错误。可是(从功能测试方面来说),需求规格不存在,甚至很少是完整的这种事是真实的,尤其会发生在产品开发快结束的时,由于需求规格更新得慢,产品它自己会取代需求规格的作用了。在越接近发布的时间,功能测试和结构化测试的区别就越模糊。

前提

        在覆盖分析的背后的一些最基本的假设,可以让我们知道这种测试技术的长处和短处。下面列出了几点最最基本的假设。

        Bugs是和控制流相关的,你可以通过变换控制流的方法来找到Bugs[Beizer1990 p.60].比如说,一个程序员写了"if (c)" 而不是 "if (!c)"。
        你可以在不知道有什么故障将会发生的情况下去找故障, 以及相信所有测试都是可信的,如果成功执行完这些测试,(没有发现错误)就代表了程序的正确性[Morell1990]。测试人员明白一个正确程序会做些什么,以及能够识别与这些正确行为的差异。
        其它的假设包括了,可完成的规格,没有遗漏的错误,和没有运行不到的代码。

        显然,这些假设并不是一直都有效的。覆盖分析可以找到一些疑似的bugs,但并不能够找出所有的bugs. 覆盖分析应用在要做许多判断的应用程序上所得到的好处要比它应用在以数据为中心的程序(比如说数据库应用)要多。

基本的度量方法

        现在有很多的覆盖度量方法,这里所描述的只是一些基本的度量方法以及他们的优缺点。

语句覆盖

        这种度量报告是否每一条可执行语句都被测过了。它也同时可以被叫为,行覆盖,段覆盖[Ntafos1988],C1[Beizer1990 p.75],以及基本的块覆盖。基本块覆盖是和语句覆盖是一样的,除了它们测量的最基本代码单位有所不同。基本块覆盖的基本单位是每一个非分支语句的序列。

        我不是太鼓励去使用描述得不太准确的名字 C1。人们有时会使用C1去标识判定覆盖。因此这个术语就存在了二义性了。

        这种度量的最主要好处就是直接应用到被测对象代码里,不需要再处理代码。性能监视器[***]通常会使用这种度量。它的主要坏处就是它对一些控制结构不敏感。举个下面的C/C++的代码片段例子来说:

int* p = NULL;
if (condition)
p = &variable;
*p = 123;

        在没有一个测试用例能够走假分支的情况下,语句覆盖仍然会认为这段代码被完全覆盖了。但事实上,只要if 条件能够走到假分支的话,这段代码就会失败。这就是语句覆盖的最大的缺点。If语句是非常普遍的。

        语句覆盖并不报告循环是否达到了他们的停止条件情况,它只报告这个循环体是否被执行过。但在C,C++,和JAVA里,这种限制会影响到包含了BREAK语句的循环。

        由于DO-WHILE循环不管怎么样都会执行至少一次,语句覆盖会把它看作与非分支语句同类。语句覆盖对逻辑操作符完全无视,它还不能够区别连续的SWITCH标签。

        和非判断语句相比,测试用例一般情况下和判断语句更加相关。你应该不会为了连续10句非分支语句写10个单独的测试用例吧?通常情况下,我们都只会用一个测试用例。举个例子来讲,有一个IF-ELSE语句,在THEN子句里包含了一条语句,在ELSE子句里包含了99条语句。当在走过了这两个可能的路径其中任何一条,语句覆盖会给出相差很大的结果,要不是1%,要不就是99%。基本块覆盖就可以解决这个问题。

        在支持语句覆盖比其它度量要好的一个论点就是bugs是均匀的颁在代码中的,因此可执行语句被覆盖的百分比,就可以反应到故障能够找到的百分经。然而,我们最基本的四种假设其中之一说的就是,故障是和控制流相关的,并不是和计算相关。而且,我们可以合理的预期到程序员将会把分支数和语句数保持在一定的比例上。

        总之,计算性的语句影响这种度量的程度要比判定影响的程度要大。

51/512345>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号