简体   繁体   English

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

[英]code coverage of xDebug and PHPUnit says 100%, in fact it is not

I have the following function: 我有以下功能:

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

My Test for this function is not covering the lines throwing the exception. 我对此函数的测试不包括抛出异常的行。 But PHPUnit tells me the first 'throw'-statement is coverd, the second not. 但PHPUnit告诉我第一个'throw'语句被覆盖,第二个没有。 Maybe the first is interpreted, but it is not executed. 也许第一个被解释,但它没有被执行。

So I don't want to get the message '100%' if I have not reached 100%. 因此,如果我没有达到100%,我不希望得到“100%”的消息。

Is this a bug in xDebug or do I have the possibility to configure xDebug/PHPUnit? 这是xDebug中的错误还是我有可能配置xDebug / PHPUnit?

xDebug's code coverage metrics are statement-based rather than line-based. xDebug的代码覆盖率指标是基于语句而不是基于行的。 What this means is that a control structure without a block enclosed in braces is treated as a single statement. 这意味着没有用括号括起来的块的控制结构被视为单个语句。 To let xDebug see the throw line as separate from the if() test, surround it with braces as you did in the second statement. 要让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
}

This happens because xDebug can't provide better data, as it is only aware of statements and not of 'lines' and is documented in the PHPUnit documentation under: 发生这种情况是因为xDebug无法提供更好的数据,因为它只知道语句而不是“行”,并在PHPUnit文档中记录:

Code coverage analysis - Edge Cases : 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();
}

The same goes for the $x ? $y : $z; $x ? $y : $z; $x ? $y : $z; construct. 构造。 The only way to avoid this behavior is to add curly braces. 避免此行为的唯一方法是添加花括号。

Its pretty bad when you have to modify your source to overcome flaws of the tools you are using. 当您必须修改源代码以克服正在使用的工具的缺陷时,它非常糟糕。

Our PHP Test Coverage Tool doesn't have this problem. 我们的PHP测试覆盖率工具没有这个问题。

In addition, if you place several statements in the same line, ours will track them individually. 此外,如果您在同一行中放置多个语句,我们将单独跟踪它们。 I believe XDebug will mark the "line" as covered if any part of the first statement in the line is covered. 我相信,如果该行中第一个语句的任何部分被覆盖,XDebug将标记为“行”。 I believe it will do this even for the following: 我相信即使对于以下内容它也会这样做:

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

So you will get "false" coverage reported for the block controlled by the conditional, even if the conditional is always false. 因此,即使条件始终为假,您也会为条件控制的块报告“错误”覆盖。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM