【问题标题】:How to configure PHPUnit to regard dataprovider error as failure and not warning?如何配置 PHPUnit 将 dataprovider 错误视为失败而不是警告?
【发布时间】:2019-04-02 11:11:34
【问题描述】:

我使用 PHPUnit 运行我的 PHP 单元测试。当数据提供者加载失败时,它会导致警告,而不是失败。

在 PHPUnit 版本 4 之前,当数据提供程序无法加载时,PHPUnit 输出中会显示失败。 从 PHPUnit 5 开始,改为发出警告。这是使用脚本运行测试时的问题(例如在持续集成中),所以我看不到结果。

另一个区别是使用 PHP 5 和 PHP 7 运行代码时。使用 PHP 5 运行测试时,我没有看到 PHPUnit 输出,而是立即得到一个 PHP 致命错误。使用 PHP 7,它仅在 PHPUnit 进行失败测试时显示失败/警告。这让我相信这与 PHPUnit 设置的 error_handler 有关,它可以捕获 PHP7 抛出的错误,但 PHP5 没有。

这是我的 PHP 代码:

class TestTest extends PHPUnit_Extensions_Database_TestCase
{
    /**
     * @dataProvider provider_sample
     */

    public function test_sample($foo)
    {
        $this->assertString($foo);
    }

    public function provider_sample()
    {
        return [
            [ClassName::string] // no such class, this should fail
        ];
    }

    public function getDataset()
    {
        return new ArrayDataSet([]);
    }
}

以下是运行 PHPUnit 4 的结果:

PHPUnit 4.8.36 by Sebastian Bergmann and contributors.

Runtime:        PHP 7.2.5
Configuration:  /home/some-path/phpunit.xml
Warning:        The Xdebug extension is not loaded
                No code coverage will be generated.

F

Time: 120 ms, Memory: 14.00MB

There was 1 failure:

1) Warning
The data provider specified for TestTest::test_sample is invalid.
Class 'ClassName' not found

FAILURES!
Tests: 1, Assertions: 0, Failures: 1.

这是使用 PHPUnit 5 运行相同代码的结果:

PHPUnit 5.7.21 by Sebastian Bergmann and contributors.

Runtime:       PHP 7.2.5
Configuration: /home/some-path/phpunit.xml
Error:         No code coverage driver is available

W                                                                   1 / 1 (100%)

Time: 99 ms, Memory: 14.00MB

There was 1 warning:

1) Warning
The data provider specified for TestTest::test_sample is invalid.
Class 'ClassName' not found

WARNINGS!
Tests: 1, Assertions: 0, Warnings: 1.

PHPUnit 4 的结果是我所期望和想要的。 有没有办法将 PHPUnit 5 及更高版本配置为相同的行为?

【问题讨论】:

  • 也许在一般意义上,在任何数据提供者中,您需要首先验证您是否确实可以生成有效数据,如果不能,可能会抛出异常。在这种情况下,您可以使用 class_exists() 来查看是否可以创建有效数据,在这种情况下是 ClassName 对象。如果不是,那么我认为抛出异常应该会导致测试失败。
  • 除了抛出异常之外,您也可以使用$this->fail()$this->assertTrue(false) 手动使测试失败,但我不确定它们是否在数据提供程序方法中工作。您也许可以使用$this->assertTrue(class_exists('ClassName', true))
  • @Huy,这太具体了。我希望每次数据提供者无法正确解决时 - 得到通知。 IE。获得失败而不是警告。
  • 也许看到这个:stackoverflow.com/questions/41057013/…。 “...数据提供程序在调用 setUpBeforeClass 静态方法和 ..setUp 方法之前执行...这是 PHPUnit 能够计算测试总数所必需的。”所以从技术上讲,dataprovider 是在类中的第一个测试运行之前执行的。它不是测试的一部分,而是设置的一部分。所以我不确定是否有办法通过数据提供者使测试失败 - 仅作为设置期间的错误。也许其他人知道更好的方法
  • @Huy 从 PHPUnit 的角度来看,类不能自动加载或数据提供者抛出异常没有区别,它们都以PHPUnit_Framework_Warning 结尾。 PHPUnit 没有建议改变它的方法,@sebastian-bergmann 对此非常坚定:github.com/sebastianbergmann/phpunit/issues/…

标签: php phpunit


【解决方案1】:

我认为您不能完全按照您的要求做,但是如果您想将 PHPUnit 与持续集成服务器(例如 Jenkins)集成,那么您可以生成一个与 JUnit 兼容的报告并报告警告作为错误,并告诉 Jenkins 使用它而不是 PHPUnit 报告。

为此,您需要扩展 PHPUnit 附带的 JUnit 记录器:

use PHPUnit\Util\Log\JUnit;

class MyJUnit extends Junit {
    public function addWarning(Test $test, Warning $e, float $time): void {
        $this->addError($test, $e, $time);
    }
}

并在phpunit.xml注册为监听器:

<listeners>
  <listener class="MyJUnit" file="MyJUnit.php">
    <arguments>
      <!-- 
        Print the output to the file instead of stdout 
        which is the default.
      -->
      <string>junit.xml</string> 
    </arguments>
  </listener>
</listeners>

最后,进入 Jenkins 设置并添加一个 JUnit 作业,指定输出文件的位置。

【讨论】:

  • 谢谢!通过一些调整,这与我实际需要的一样接近。
【解决方案2】:

检查文件名并导入

 require_once 'ClassName.php';

【讨论】:

  • 这确实避免了这个问题,但我想要实现的是,如果 given 无法加载 ClassName,我想要发出失败,而不是警告
猜你喜欢
  • 1970-01-01
  • 2020-08-21
  • 1970-01-01
  • 2020-10-21
  • 1970-01-01
  • 1970-01-01
  • 2018-03-18
  • 2013-12-11
  • 1970-01-01
相关资源
最近更新 更多