首页 文章

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

提问于
浏览
0

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

问题

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

如何重现

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

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

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

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

  • 然后,我通过删除完整的 src/Controller 目录,控制器的测试以及应用程序配置中对该directroy的引用来消除控制器 .

  • 然后我用2个命令创建一个 src/Command 目录: DummyACommand.phpDummyBCommand.php .

  • 然后,我创建了一个愚蠢的测试,执行 assertTrue( true ); 以报告某些内容,但根本不调用命令 .

Result: 这是正确的 . 然后在 Command 目录上报告0%,如下所示:

Result of all Command section

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

Commands at 0%

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

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 ); 仍在那里 .

Result: 现在,如果我查看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改变了对命令B中“潜在可执行”的考虑,我不明白为什么 .

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

Full report shows a false coverage indication

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

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

所以......问题:

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

我怎样才能指示PhpUnit将B视为未被发现?

谢谢!哈维 .

1 回答

  • 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上的最新稳定版(或者至少是更新向导建议我安装的版本) .

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

相关问题