软件工程/工具/代码覆盖率简介
代码覆盖率是软件测试中使用的一种度量。它描述了程序源代码被测试的程度。它是一种直接检查代码的测试形式,因此是一种白盒测试形式。[1]随着时间的推移,代码覆盖率的使用已经扩展到数字硬件领域,其当代设计方法依赖于硬件描述语言 (HDL)。
代码覆盖率是最早为系统软件测试发明的方法之一。第一个公开发表的参考文献是 Miller 和 Maloney 在 1963 年的《ACM 通讯》中发表的。
代码覆盖率是航空电子设备安全认证中的一个考虑因素。联邦航空管理局 (FAA) 对航空电子设备进行认证的标准记录在 DO-178B 中。[2]
为了衡量测试套件对程序的测试程度,使用一个或多个覆盖率标准。
有许多覆盖率标准,主要标准包括:[3]
- 函数覆盖率 - 程序中的每个函数(或子例程)是否都被调用过?
- 语句覆盖率 - 程序中的每个节点是否都被执行过?
- 判定覆盖率(与分支覆盖率不同 - 请参见 Position Paper CAST10.[4]) - 程序中的每个边是否都被执行过?例如,每个控制结构(例如 IF 和 CASE 语句)中每个分支的要求是否都得到满足,以及未得到满足?
- 条件覆盖率(或谓词覆盖率) - 每个布尔子表达式是否都被评估为真和假?这并不一定意味着判定覆盖率。
- 条件/判定覆盖率 - 判定和条件覆盖率都应该得到满足。
例如,考虑以下 C++ 函数
int foo(int x, int y)
{
int z = 0;
if ((x>0) && (y>0)) {
z = x;
}
return z;
}
假设此函数是某个更大程序的一部分,并且该程序已使用一些测试套件运行过。
- 如果在执行过程中,函数“foo”至少被调用过一次,那么此函数的函数覆盖率就得到满足。
- 此函数的语句覆盖率将得到满足,例如,如果它被调用为
foo(1,1)
,因为在这种情况下,函数中的每一行都会被执行,包括z = x;
。 - 调用
foo(1,1)
和foo(1,0)
的测试将满足判定覆盖率,因为在第一种情况下,if
条件得到满足并执行z = x;
,而在第二种情况下则没有。 - 条件覆盖率可以通过调用
foo(1,1)
、foo(1,0)
和foo(0,0)
的测试来满足。这些测试是必要的,因为在前两种情况下(x>0)
的值为true
,而在第三种情况下则为false
。同时,第一种情况下(y>0)
的值为true
,而在第二种和第三种情况下则为false
。
在像 Pascal 这样的语言中,标准布尔运算不进行短路,条件覆盖率并不一定意味着判定覆盖率。例如,考虑以下代码片段
if a and b then
条件覆盖率可以通过两种测试来满足
a=true
,b=false
a=false
,b=true
但是,这组测试并不满足判定覆盖率,因为在这两种情况下,if
条件都不会满足。
可能需要故障注入才能确保所有条件和异常处理代码的分支在测试期间都有足够的覆盖率。
对于安全关键型应用程序(例如航空电子软件),通常要求满足修改后的条件/判定覆盖率 (MC/DC)。此标准扩展了条件/判定标准,要求每个条件都应独立地影响判定结果。例如,考虑以下代码
if (a or b) and c then
条件/判定标准将通过以下测试集得到满足
- a=true, b=true, c=true
- a=false, b=false, c=false
但是,以上测试集不会满足修改后的条件/判定覆盖率,因为在第一个测试中,'b' 的值,在第二个测试中,'c' 的值不会影响输出。因此,需要以下测试集来满足 MC/DC
- a=false, b=false, c=true
- a=true, b=false, c=true
- a=false, b=true, c=true
- a=true, b=true, c=false
粗体值会影响输出,每个变量必须至少作为一次影响值为假,一次影响值为真。
此标准要求测试每个判定中的所有条件组合。例如,上一节中的代码片段将需要八个测试
- a=false, b=false, c=false
- a=false, b=false, c=true
- a=false, b=true, c=false
- a=false, b=true, c=true
- a=true, b=false, c=false
- a=true, b=false, c=true
- a=true, b=true, c=false
- a=true, b=true, c=true
还有一些其他不太常用的覆盖率标准
- 线性代码序列和跳转 (LCSAJ) 覆盖率 - 每个 LCSAJ 是否都被执行过?
- JJ-路径覆盖率 - 所有跳转到跳转路径[5](也称为 LCSAJ)是否都被执行过?
- 路径覆盖率 - 代码给定部分中的所有可能路径是否都被执行过?
- 入口/出口覆盖率 - 函数的所有可能调用和返回是否都被执行过?
- 循环覆盖率 - 每个可能的循环是否都被执行过零次、一次和多次?
安全关键型应用程序通常要求证明测试已实现某种代码覆盖率的 100%。
上述某些覆盖率标准是相互关联的。例如,路径覆盖率意味着判定、语句和入口/出口覆盖率。判定覆盖率意味着语句覆盖率,因为每个语句都是分支的一部分。
如上所述,完全路径覆盖通常不切实际或不可能。任何包含一系列 决策的模块,最多可能包含 条路径;循环结构会导致无限条路径。许多路径也可能是不可行的,因为没有输入到被测程序可以导致执行该特定路径。但是,已被证明不可能找到识别不可行路径的通用算法(这样的算法可以用于解决停止问题)。[6] 用于实际路径覆盖测试的方法试图识别仅在循环执行次数上有所不同的代码路径类别,为了实现“基本路径”覆盖,测试人员必须覆盖所有路径类别。
在实践中
[edit | edit source]目标软件是用特殊选项或库构建的,或者在特殊环境下运行,这样程序中执行的每个函数都映射回源代码中的函数点。此过程允许开发人员和质量保证人员查找在正常情况下很少或从未访问过的系统部分(错误处理等),并帮助测试工程师确保测试了最重要的条件(函数点)。然后分析生成的结果,查看代码中哪些部分尚未执行,并根据需要更新测试以包含这些部分。结合其他代码覆盖方法,目标是开发一套严格且可管理的回归测试。
在软件开发环境中实施代码覆盖策略时,必须考虑以下因素:
- 最终产品认证的覆盖率要求是什么,如果是,需要达到多少代码覆盖率?典型的严格程度进展如下:语句覆盖,分支/决策覆盖,修改条件/决策覆盖(MC/DC),LCSAJ(线性代码序列和跳转)
- 是否会针对验证被测系统要求的测试衡量代码覆盖率(DO-178B)?
- 生成的机器码是否可以直接追溯到源代码语句?某些认证(例如 DO-178B A 级)要求在汇编级别进行覆盖,如果不是这样:“那么,应该对机器码执行额外的验证以确定这些生成的代码序列的正确性”(DO-178B)para-6.4.4.2。[7]
测试工程师可以查看代码覆盖率测试结果,帮助他们设计测试用例和输入或配置集,以提高重要功能的代码覆盖率。测试人员使用的两种常见的代码覆盖率形式是语句(或行)覆盖率和路径(或边)覆盖率。行覆盖率根据执行测试时执行的代码行数来报告测试的执行覆盖范围。边覆盖率报告执行测试时执行的分支或代码决策点。它们都报告一个覆盖率指标,以百分比衡量。这个指标的含义取决于使用过哪些形式的代码覆盖率,因为 67% 的路径覆盖率比 67% 的语句覆盖率更全面。
一般来说,代码覆盖率工具和库会消耗一定量的性能和/或内存或其他资源,这对于软件的正常运行来说是不可接受的。因此,它们只在实验室中使用。正如人们所期望的那样,有一些软件类别不能实际进行这些覆盖测试,尽管可以通过分析而不是直接测试来近似地实现一定程度的覆盖映射。
也有一些缺陷会受到这些工具的影响。特别是,一些竞争条件或类似的实时敏感操作在代码覆盖环境下运行时可能会被掩盖;相反,由于测试代码的额外开销,一些这些缺陷可能会更容易发现。
软件工具
[edit | edit source]C/C++ 工具
[edit | edit source]- CodeScroll 控制器测试器
- VectorCAST
- Parasoft C++test
- Cantata++
- Insure++
- IBM Rational Pure Coverage
- Tessy
- Testwell CTC++
- Trucov
C# .NET 工具
[edit | edit source]- Parasoft dotTEST
- NCover
- Testwell CTC++(带 C# 插件)
Java 工具
[edit | edit source]- Parasoft Jtest
- Clover
- Cobertura
- Structure 101
- EMMA
- Serenity
- Testwell CTC++(带 Java 和 Android 插件)
PHP 工具
[edit | edit source]- PHPUnit,还需要 Xdebug 才能生成覆盖率报告
硬件工具
[edit | edit source]- Aldec
- Atrenta
- Cadence Design Systems
- JEDA Technologies
- Mentor Graphics
- Nusym Technology
- Simucad Design Automation
- Synopsys
备注
[edit | edit source]- ↑ Kolawa, Adam (2007). Automated Defect Prevention: Best Practices in Software Management. Wiley-IEEE Computer Society Press. p. 254. ISBN 0470042125.
{{cite book}}
: More than one of|pages=
and|page=
specified (help); Unknown parameter|coauthors=
ignored (|author=
suggested) (help) - ↑ RTCA/DO-178(b), 空中系统和设备认证软件考虑因素,航空无线电技术委员会,1992 年 12 月 1 日。
- ↑ Glenford J. Myers (2004). The Art of Software Testing, 2nd edition. Wiley. ISBN 0471469122.
- ↑ [1]
- ↑ M. R. Woodward, M. A. Hennell, "关于两种控制流覆盖标准之间的关系:所有 JJ 路径和 MCDC", 信息与软件技术 48 (2006) pp. 433-440
- ↑ Dorf, Richard C.: 计算机、软件工程和数字设备,第 12 章,第 15 页。CRC 出版社,2006 年。 ISBN 0849373409,9780849373404;通过 谷歌图书搜索
- ↑ 机载系统和设备认证中的软件注意事项 - RTCA/DO-178B,RTCA 公司,华盛顿特区,1992 年 12 月
- 任意语言的分支覆盖变得容易
- 代码覆盖率分析 by Steve Cornett
- 代码覆盖率简介
- 关于代码覆盖率和工具选择的全面论文 by Vijayan Reddy, Nithya Jayachandran
- 开发工具(Java) at DMOZ
- 开发工具(通用) at DMOZ
- 数字计算机程序的系统错误分析
- FAA CAST 职位论文 [2]