如何配置PHPUnit将dataprovider错误视为失败而不是警告?

3
我使用PHPUnit运行我的PHP单元测试。当数据提供程序未能加载时,会出现警告而非失败。
在PHPUnit 4版本之前,当数据提供程序无法加载时,PHPUnit输出中将显示失败信息。从PHPUnit 5开始,会发出警告。这对于使用脚本运行测试(例如在持续集成中)时很有问题,因为我看不到结果。
另一个区别是在使用PHP 5和PHP 7运行代码时的表现不同。在使用PHP 5运行测试时,我不会看到PHPUnit输出,而是会立即收到PHP致命错误。而在PHP 7上运行时,只有当PHPUnit到达失败的测试时才显示失败/警告。这让我相信这与PHPUnit设置的错误处理程序有关,可以捕获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。如果不能,则抛出异常应该会导致测试失败。 - Huy
除了抛出异常之外,您还可以使用 $this->fail()$this->assertTrue(false) 来手动失败测试,但我不确定它们是否可以在数据提供程序方法中工作。 您可以尝试使用 $this->assertTrue(class_exists('ClassName', true)) - Huy
@Huy,这太具体了。我希望每次数据提供程序无法正确解析时都能得到通知。即获得失败而不是警告。 - noam
也许可以看一下这个链接:https://dev59.com/8p3ha4cB1Zd3GeqPQzZ7。"...数据提供者在调用setUpBeforeClass静态方法和setUp方法之前执行...这是为了PHPUnit能够计算测试的总数。" 因此,从技术上讲,dataprovider在类中的第一个测试运行之前就已经被执行了。它不是测试的一部分,而是设置的一部分。因此,我不确定是否有一种方法可以使用dataprovider使测试失败 - 只能在设置期间作为错误。也许其他人知道更好的方法。 - Huy
从PHPUnit的角度来看,无论一个类不能自动加载还是从数据提供程序中抛出异常,它们最终都会成为PHPUnit_Framework_Warning。PHPUnit并不建议更改它,@sebastian-bergmann对此非常坚定:https://github.com/sebastianbergmann/phpunit/issues/2228#issuecomment-336609090 - ob-ivan
2个回答

0
我认为你可能无法完全实现你要求的内容,但是如果你想将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作业,指定输出文件的位置。

谢谢!经过一些调整,这已经是我所需要的最接近的结果了。 - noam

0

检查文件名并导入

 require_once 'ClassName.php';

这确实避免了问题,但是我想要实现的是,如果给定无法加载_ClassName_,我希望发出失败而不是警告 - noam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接