xDebug和PHPUnit的代码覆盖率为100%,实际上并非如此

时间:2012-02-16 08:23:54

标签: php phpunit code-coverage xdebug

我有以下功能:

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

我对此功能的测试并未涵盖抛出异常的行。但PHPUnit告诉我第一个'throw'语句被覆盖,第二个没有。也许第一个被解释,但它没有被执行。

所以如果我没有达到100%,我不想得到'100%'这个消息。

这是xDebug中的错误还是我可以配置xDebug / PHPUnit?

3 个答案:

答案 0 :(得分:5)

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

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

VS

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

答案 1 :(得分: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;构造也是如此。避免此行为的唯一方法是添加花括号。

答案 2 :(得分:-1)

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

我们的PHP Test Coverage Tool没有此问题。

此外,如果您在同一行中放置多个语句,我们将单独跟踪它们。我相信,如果该行中第一个语句的任何部分被覆盖,XDebug将标记为“行”。我相信即使对于以下内容它也会这样做:

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

因此,即使条件始终为假,您也会为条件控制的块报告“虚假”覆盖。