即使在所有测试完成之前,如何显示失败的PHPUnit测试的名称

时间:2019-02-27 18:58:15

标签: php phpunit phpunit-testing

我已将测试分为不同的组,以便在绝对必要之前不必费心运行最慢的测试。

但是,有些仍然很慢。

因此,我很乐意甚至在整个测试套件完成运行之前,查看失败或有错误的测试名称。

例如当前,当我运行 phpunit tests / Unit / --verbose 时,我看到这样的输出:

Sebastian Bergmann和贡献者的
  PHPUnit 7.5.1。

运行时:带有Xdebug 2.6.0的PHP 7.2.14-1 + ubuntu16.04.1 + deb.sury.org + 1
配置:/home/vagrant/Code/myproject/phpunit.xml

........F.....
 

但是,即使我看到“ F”字样,也需要等待很长时间才能看到哪个测试失败了。

我希望能够允许测试继续运行,但同时开始调查该特定测试以查看其失败原因。

如何?

2 个答案:

答案 0 :(得分:1)

您至少有3个选择:

  1. 添加--debug标志(阅读您的评论后,这似乎无法满足您的需要,而实时显示哪些测试失败了)

  2. 创建打印机类,并将其与--printer标志一起使用

  3. 添加--testdox标志

很久以前,我必须自己做打印机,因为我需要显示测试花费了多长时间。因此,基本上我正在打印测试的开始时间,名称和花费的时间。您可以使用此代码并使其适应您的需求。

您需要创建一个新类(通常在/ tests directoy下)。确保此类扩展了PHPUnit_TextUI_ResultPrinter。然后在phpunit.xml文件中,将这些设置添加到

     printerFile="tests/TestDurationPrinter.php"  <-- filename 
     printerClass="TestDurationPrinter   <-- Class you created.

我的打印机如下:

    class TestDurationPrinter extends \PHPUnit_TextUI_ResultPrinter
    {
    /**
     * @param PHPUnit_Framework_Test|PHPUnit_Extensions_PhptTestCase $test
     */
    public function startTest(PHPUnit_Framework_Test $test)
    {
        $this->write(sprintf(
            "\nRunning '%s::%s'...",
            get_class($test),
            $test->getName()
        ));
    }

    /**
     * @param PHPUnit_Framework_Test|PHPUnit_Extensions_PhptTestCase $test
     * @param float $time
     */
    public function endTest(PHPUnit_Framework_Test $test, $time)
    {
        $this->write(sprintf(
            "ended and took ~ %s seconds.",
            round($time)
        ));
    }
}

对于您而言,我认为使用--testdox就足够了。如果它不起作用,那么我建议您创建自己的打印机,请记住,您仍然需要访问测试结果(我不知道该怎么做),因此您需要在Google上进行搜索。

希望对您有帮助。

编辑:您可以做的另一件事是添加标记

--stop-on-error
,以便在出现错误时立即停止测试。还有
--stop-on-failure
(我想这是您想要的)。我总是同时使用这两种方法,因为我的测试套件有大约800个测试,整个执行过程大约需要3分钟。

答案 1 :(得分:0)

我感谢Guillermo Mansilla's answer,并且现在我终于想出了我更喜欢的东西:

1)我编辑了 phpunit.xml <phpunit>标签,其中包括:

printerFile="tests/CustomPhpUnitConsolePrinter.php"
printerClass="CustomPhpUnitConsolePrinter"

2)我的 CustomPhpUnitConsolePrinter.php 是这样的:

<?php

class CustomPhpUnitConsolePrinter extends \PHPUnit\TextUI\ResultPrinter {

    protected static $skippedTests = [];
    protected static $testsWithUnknownStatus = [];

    /**
     * @param \PHPUnit\Framework\Test|\PHPUnit\Extensions\PhptTestCase $test
     * @param float $time
     */
    public function endTest(\PHPUnit\Framework\Test $test, $time): void {
        parent::endTest($test, $time);
        $status = $test->getStatus();
        if ($status != \PHPUnit\Runner\BaseTestRunner::STATUS_PASSED) {//https://stackoverflow.com/a/6744246/470749
            if ($status == \PHPUnit\Runner\BaseTestRunner::STATUS_SKIPPED) {
                self::$skippedTests[] = \PHPUnit\Util\Test::describeAsString($test);
            } else if ($status == \PHPUnit\Runner\BaseTestRunner::STATUS_UNKNOWN) {
                self::$testsWithUnknownStatus[] = \PHPUnit\Util\Test::describeAsString($test);
            } else {
                $this->write(\sprintf(PHP_EOL . "[%s]", \PHPUnit\Util\Test::describeAsString($test)));
            }
        }
    }

    protected function printFooter(\PHPUnit\Framework\TestResult $result): void {
        if (self::$skippedTests) {
            $this->write(PHP_EOL . strtoupper('► Skipped tests:') . PHP_EOL);
            $this->write(implode(PHP_EOL, self::$skippedTests) . PHP_EOL);
        }
        if (self::$testsWithUnknownStatus) {
            $this->write(PHP_EOL . strtoupper('► Tests with Unknown status:') . PHP_EOL);
            $this->write(implode(PHP_EOL, self::$testsWithUnknownStatus) . PHP_EOL);
        }
        parent::printFooter($result);
    }

}

3)我还在结束</phpunit>标记之前添加了本节(请参见docs):

<logging>
    <!--        https://stackoverflow.com/a/52377685/470749-->
    <log type="testdox-html" target="./storage/logs/testdox.html"/>
</logging>