xDebug和PHPUnit的代码覆盖率说是100%,但事实并非如此



我有以下功能:

function foo($p)
{
    if ($p == null)
        throw new Exception('bla');
    if ($p == null)
    {
        throw new Exception('bla');
    }
    [...]
}

我对这个函数的测试没有覆盖引发异常的行。但PHPUnit告诉我,第一个抛出声明被掩盖了,第二个没有。也许第一个被解释了,但它没有被执行。

因此,如果我还没有达到100%,我不想收到"100%"的消息。

这是xDebug中的错误吗?还是我有可能配置xDebug/PHPUnit?

xDebug的代码覆盖率度量是基于语句的,而不是基于行的。这意味着,一个没有用大括号括起来的块的控制结构被视为一个单独的语句。要让xDebug将throw行与if()测试分开,请像在第二条语句中那样用大括号将其括起来。

if ($p == null)                    // statement 1
    throw new Exception('bla');    // rest of statement 1

与。

if ($p == null) {                  // statement 1
    throw new Exception('bla');    // statement 2
}

发生这种情况是因为xDebug无法提供更好的数据,因为它只知道语句而不知道"行",并且在PHPUnit文档中记录在:下

Code coverage analysis - Edge Cases

<?php
// Due to how code coverage works internally these two lines are special.
// This line will show up as non executable
if(false)
    // This line will show up as covered because it is actually the 
    // coverage of the if statement in the line above that gets shown here!
    will_also_show_up_as_coveraged();
// To avoid this it is necessary that braces are used
if(false) {
    this_call_will_never_show_up_as_covered();
}

$x ? $y : $z;构造也是如此。避免这种行为的唯一方法是添加大括号。

当您必须修改源代码以克服所使用工具的缺陷时,情况非常糟糕。

我们的PHP测试覆盖工具没有这个问题。

此外,如果您将多个语句放在同一行,我们将单独跟踪它们。我相信,如果覆盖了行中第一个语句的任何部分,XDebug会将"行"标记为已覆盖。我相信它会做到这一点,即使是对以下方面:

if (... )  { .... }

因此,即使条件总是false,您也会得到由条件控制的块的"false"覆盖率报告。

最新更新