PhpUnit + Symfony:为什么覆盖率显示白色而不是红色,并且在未经测试的类上显示100%?

时间:2017-09-09 17:50:49

标签: symfony phpunit code-coverage function-coverage

我遇到了问题,我创建了一个空项目来重现最小的情况,使其可重复。

问题

具有未经测试的课程的项目提供100%的覆盖率。有问题的方法是从其他地方间接调用。虽然在测试另一个类时间接调用了未测试类的其他方法。

如何重现

步骤1:创建一个空的新symfony项目。

  • 我使用此命令创建了一个新的symfony 3.3项目:symfony new coverage_trial_to_be_deleted

结果:如果我运行vendor/bin/simple-phpunit --coverage-html coverageReport,我会按预期获得一个经过全面测试的项目,因为该示例包含一个默认控制器的默认测试。

步骤2:删除控制器并创建两个命令,但不要覆盖它们。

  • 然后我通过删除完整的src/Controller目录,控制器的测试以及应用程序配置中对该directroy的引用来消除控制器。
  • 然后我创建了一个包含2个命令的src/Command目录:DummyACommand.phpDummyBCommand.php
  • 然后我创建了一个愚蠢的测试,执行assertTrue( true );来报告,但根本不调用命令。

结果:这是正确的。然后它在Command目录上报告0%,如下所示:

Result of all Command section

特别是在Command内,我可以看到2个命令为0%,这是正常的:

Commands at 0%

最后,如果我输入第二个命令,&#34; B&#34;命令,说DummyBCommand,我仍然可以看到configure()execute()方法都没有被覆盖,我看到,正如预期的那样,每个方法都有一个红色区域:< / p>

Report of Command B

到此为止,一切都按预期进行。

步骤3:仅为命令A添加测试,不测试命令B.

然后我添加一个名为DummyACommandTest.php的新测试,其中包含以下内容:

<?php

declare( strict_types=1 );

namespace Tests\AppBundle\Command;

use AppBundle\Command\DummyACommand;
use Symfony\Component\Console\Tester\CommandTester;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;

class EnvironmentListCommandTest extends KernelTestCase
{
    public function testExecute()
    {
        $kernel = $this->createKernel();
        $kernel->boot();

        $application = new Application( $kernel );
        $application->add( new DummyACommand() );

        $command = $application->find( 'dummy:a' );
        $commandTester = new CommandTester( $command );
        $commandTester->execute(
            [
                'command' => $command->getName(),
            ]
        );

        $output = $commandTester->getDisplay();
        $this->assertContains( 'dummy A command', $output );
    }
}

测试按照预期给出绿灯,因为它调用DummyACommand并执行它,然后检查输出,它确实包含了预期的内容:

Tests pass with green light

它说2次测试,因为assertTrue( true );仍在那里。

结果:现在,如果我查看DummyBCommand的覆盖范围,我应该看到涵盖了configure()方法,因为测试A的事实会调用$application->find( 'dummy:a' );,我猜它探讨了所有的命令。

我真的不太了解这一点,因为我只做$application->add( new DummyACommand() );并且我不知道加载dummy:b的时间,但无论如何我们要给予这个假设是一个机会。

所以我不介意看到绿色的configure()(下图中的注释[1])。

但我不喜欢的是,然后,B的execute()而不是红色(没有人称之为执行,应该与第2步完全一样),它显示为白色!! ! :|比如注释[2]

Now command 2 has a white section instead of red section

所以出于某种原因......测试命令A使PHPUnit改变了对什么是&#34;可能的可执行文件&#34;的考虑。在命令B中,我不明白为什么。

这使得整个项目被报告为100%测试,而它是错误的,如下所示:

Full report shows a false coverage indication

但当然这些信息并不反映现实:命令B的execute()方法未被覆盖且从未执行过。

我希望报告能够告诉我75%的线路覆盖率(4个中的3个)和50%的覆盖率(1个中的2个)。

所以......问题:

为什么PhpUnit在为A类添加测试时会改变对B类潜在可执行代码的考虑?

如何指示PhpUnit将B视为未覆盖?

谢谢! 哈维。

1 个答案:

答案 0 :(得分:0)

实测值!!

快速解决方案

在此处更新xdebug库:https://xdebug.org/wizard.php

详细解决方案

正如您在问题图片中看到的那样,我使用的是Xdebug 2.4.0,因为那是我系统中的那个,一个稳定的Ubuntu 16.04

根据这个帖子:https://github.com/sebastianbergmann/php-code-coverage/issues/411在一整年中,那些人(谢谢大家)他们正在追求同样的问题:没有被报告为可执行的行。

最后他们得出的结论是XDebug中有一个错误,最后报告并更正了。

这是:xdebug将数据报告给phpunit,因此phpunit正在运行错误的假设。

我在这里升级https://xdebug.org/wizard.php(我在该主题中找到的链接),并按照指示编译了一个新的xdebug

在这里你可以看到该项目现在不是100%,但75%的行和50%的类(如预期的那样):

enter image description here

在这里你可以看到命令A报告100%(这是okey,因为它是我测试的那个)并且命令B在行中报告为50%,在类中报告为0%,因为我没有写测试它。方法configure()在内核引导和应用程序加载时运行:

enter image description here

如果我们输入命令B(即:DummyBCommand),我们终于可以看到方法execute()被标记为红色,而不是白色:

enter image description here

在此图片中,您可以在[1]中看到configure()为100%且execute()为0%,这是正确的。

[2]中,您可以看到颜色。正如预期的那样,execute()标记为红色。

最后,在[3]中你可以看到XDebug版本是2.5.4,是10 / sep / 2017上的最新稳定版(或者至少是更新向导建议我使用的版本)安装)。

所以...下载,配置,编译,安装和繁荣,完成!