Testing 数据流覆盖率

Testing 数据流覆盖率,testing,Testing,如果您编写一个程序,通常可以驱动它以覆盖所有路径。因此,100%的覆盖率很容易获得(忽略了现代编译器无论如何捕获的不可行的代码路径) 然而,100%的代码覆盖率应该意味着所有变量定义使用覆盖率也都实现了,因为变量是在程序中定义并在程序中使用的。如果涵盖了所有代码,则还应涵盖所有DU对 那么,为什么说路径覆盖率更容易获得,但数据流覆盖率通常不可能达到100%?我不明白为什么不?什么是这样一个例子?与所有可能的输入相比,实现100%的代码覆盖率更容易,因为所有可能的输入集可能非常大或实际上是无限的要

如果您编写一个程序,通常可以驱动它以覆盖所有路径。因此,100%的覆盖率很容易获得(忽略了现代编译器无论如何捕获的不可行的代码路径)

然而,100%的代码覆盖率应该意味着所有变量定义使用覆盖率也都实现了,因为变量是在程序中定义并在程序中使用的。如果涵盖了所有代码,则还应涵盖所有DU对


那么,为什么说路径覆盖率更容易获得,但数据流覆盖率通常不可能达到100%?我不明白为什么不?什么是这样一个例子?

与所有可能的输入相比,实现100%的代码覆盖率更容易,因为所有可能的输入集可能非常大或实际上是无限的要全部测试它们需要太多时间。

让我们看一个简单的函数示例:

double invert(double x) {
    return 1.0/x;
}
double multiply(double x, double y);
单元测试可能如下所示:

double y = invert(5);
double expected = 1.0/5.0;
EXPECT_EQ( expected, y );
该测试实现了100%的代码覆盖率。然而,它只有1/1.8446744e+19个可能的输入(假设双精度是64位宽)

背后的想法是,测试每一个可能的输入是不现实的,因此我们必须确定覆盖所有情况的范围

使用我的
invert()
函数,至少有两个重要的集合:{non-zero values}和{zero}

我们需要添加另一个测试,它覆盖相同的代码路径,但有不同的结果:

EXPECT_THROWS( invert(0.0) );
此外,由于测试编写者必须设计不同的可能参数集,以实现测试的完整数据输入覆盖率,因此不可能知道正确的参数集是什么

考虑这一功能:

double invert(double x) {
    return 1.0/x;
}
double multiply(double x, double y);
我的本能是为小数字编写测试,为大数字编写另一个测试,以测试溢出

但是,开发人员可能写得很差,如下所示:

double multiply(double x, double y) {
    if(x==0) return 0; 
    return 1.0 / ( (1.0/x) * (1.0/y) );
}
如果我们的测试没有使用0表示y,那么我们将错过一个bug。了解算法是如何设计的对于理解单元测试的正确输入非常重要,这就是为什么编写代码的程序员需要参与单元测试的原因