0

我正在研究这些之间的区别,但无法理解其中的区别。对我来说似乎是一样的。他们不一样吗?风险来自短路,不是吗?

语句覆盖不需要测试逻辑运算符。在 C++ 和 C 中,这些运算符是 &&、|| 和 ?:。语句覆盖率无法区分由逻辑运算符分隔的代码与语句的其余部分。在语句中执行代码的任何部分都会导致语句覆盖声明整个语句被完全覆盖。当逻辑运算符避免不必要的评估(通过短路)时,语句覆盖率给出了夸大的覆盖率测量。

void function(const char* string1, const char* string2 = NULL);
...
void function(const char* string1, const char* string2)
{
    if (condition || strcmp(string1, string2) == 0) // Oops, possible null pointer passed to strcmp
    ...
}

决策覆盖 - 一个缺点是该度量忽略了由于短路运算符而出现的布尔表达式中的分支。例如,考虑以下 C/C++/Java 代码片段:

if (condition1 && (condition2 || function1()))
    statement1;
else
    statement2;
4

2 回答 2

1

它们略有不同,但都需要短路操作来证明您正确推测的问题。

语句覆盖率问题

if (complex-condition-evaluation-with-short-circuits) 
  doAction(); 

语句覆盖率可能会记录您访问了上述两行,但您可能永远不知道您是否执行了仅评估部分复杂条件的场景。

即在你的例子中strcmp(...)曾经被执行过吗?

分支机构覆盖问题

if (complex-condition-evaluation-with-short-circuits) 
  doAction(); 
else
  doOtherAction(); 

分支覆盖可能会记录您通过(源)代码中的所有路径,但会忽略作为复杂条件评估一部分的分支(如所述)。

即在您的示例中,分支覆盖不将其||视为备用分支,并将其视为仅通过代码的两条路径,而实际上它是四个。

path1 (calls doAction) => condition1 == true, condition2 == true, function1() == ?
path2 (calls doAction) => condition1 == true, condition2 == false, function1() == true
path3 (calls doOtherAction) => condition1 == true, condition2 == false, function1() == false
path4 (calls doOtherAction) => condition1 == false, condition2 == ?, function1() == ?

我希望这有帮助

于 2013-02-21T09:16:07.317 回答
1

据我所知,这些示例中的风险来自短路,它们确实是等效的。在其他一些情况下,可能会有所不同。例如考虑以下情况:

if (a>5)
    b = 6
if (a<20)
    c = 4 + b

对于语句覆盖率,测试就足够了a=10(所有行都将被执行)并且测试将通过。

对于决策覆盖,有必要评估所有 if 语句的真假。例如,可以通过两个测试a=30和100% 的决策覆盖率来实现a=0。后者将失败,因为b在这种情况下尚未设置变量。

因此,决策覆盖更强大;实际上 100% 的决策覆盖率保证了 100% 的语句覆盖率,但反之则不然。但是,仍然可以构建决策覆盖率不足以暴露错误的示例,无论该语言是否存在短路。

让我们考虑一种不会发生短路的情况

if (a>0 || b>0)
    c = 5 / b

让我们用输入数据 a=0 来测试它;b=1;a=0,b=0。第一个足以提供语句覆盖。两者一起提供决策覆盖。但两者都没有在 if 中公开除以零。

于 2013-02-21T09:17:42.373 回答