语句覆盖不要求测试逻辑运算符。在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;
答案 0 :(得分: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() == ?
我希望这会有所帮助
答案 1 :(得分:1)
据我所知,这些例子中的风险来自于短路,它们确实是等同的。在其他一些情况下可能会有所不同。例如,考虑以下情况:
if (a>5)
b = 6
if (a<20)
c = 4 + b
对于语句覆盖,使用a=10
进行测试就足够了(所有行都将被执行)并且测试将通过。
对于决策覆盖,有必要将所有if语句评估为true和false。例如,通过两个测试a=30
和a=0
可以实现100%的决策覆盖率。后者将失败,因为在这种情况下尚未设置变量b
。
因此,决策覆盖范围更广;实际上,100%的决策覆盖率保证100%的报表覆盖率,但反之则不然。但是,仍然可以构建一些示例,其中决策覆盖率不足以暴露错误,无论语言是否有短路。
让我们考虑一下不会出现短路的情况
if (a>0 || b>0)
c = 5 / b
让我们用输入数据a = 0来测试它; B = 1; a = 0,b = 0。第一个足以提供声明覆盖。两者一起提供决策覆盖。但是,在if。
中都没有将除法暴露为零