如何跳过PHPUnit中的错误测试?

时间:2016-08-24 18:08:16

标签: php unit-testing testing phpunit

当依赖的数据集与数据集有错误时,如何让PHPUnit跳过测试?

作品

如果我的数据提供者只有导致错误的东西,那么它将适当地跳过依赖测试。 注意 Skipped: 1

class DataProviderDependsTest extends PHPUnit_Framework_TestCase
{
    public function getDataProvider(){
      return [
        ['non-existent_file.txt'],
      ];
    }

    /**
     *  @dataProvider getDataProvider
     */
    public function testCanBeDependedOn($data){
      $actual = file_get_contents($data);
      $this->assertSame('expected',$actual);
    }

    /**
     *  @dataProvider getDataProvider
     *  @depends testCanBeDependedOn
     */
    public function testCanDepend($data){
      $this->assertTrue(false);
    }
}
PHPUnit 5.5.0 by Sebastian Bergmann and contributors.

ES                                                                  2 / 2 (100%)

Time: 28 ms, Memory: 4.00MB

There was 1 error:

1) DataProviderDependsTest::testCanBeDependedOn with data set #0 ('non-existent_file.txt')
file_get_contents(non-existent_file.txt): failed to open stream: No such file or directory

/home/xenial/phpunittest/test.php:16

ERRORS!
Tests: 1, Assertions: 0, Errors: 1, Skipped: 1.

不起作用

但是,如果我向提供程序添加一个好的数据,那么尽管其余部分导致了错误,PHPUnit仍会继续执行 所有 依赖测试(甚至相应的数据集都有错误)。它不会跳过任何东西。 注意['real_file.txt'],添加到数据提供商。

class DataProviderDependsTest extends PHPUnit_Framework_TestCase
{
    public function getDataProvider(){
      return [
        ['real_file.txt'],
        ['non-existent_file.txt'],
      ];
    }

    /**
     *  @dataProvider getDataProvider
     */
    public function testCanBeDependedOn($data){
      $actual = file_get_contents($data);
      $this->assertSame('expected',$actual);
    }

    /**
     *  @dataProvider getDataProvider
     *  @depends testCanBeDependedOn
     */
    public function testCanDepend($data){
      $this->assertTrue(false);
    }
}
PHPUnit 5.5.0 by Sebastian Bergmann and contributors.

.EFF                                                                4 / 4 (100%)

Time: 19 ms, Memory: 4.00MB

There was 1 error:

1) DataProviderDependsTest::testCanBeDependedOn with data set #1 ('non-existent_file.txt')
file_get_contents(non-existent_file.txt): failed to open stream: No such file or directory

/home/xenial/phpunittest/test.php:16

--

There were 2 failures:

1) DataProviderDependsTest::testCanDepend with data set #0 ('real_file.txt')
Failed asserting that false is true.

/home/xenial/phpunittest/test.php:25

2) DataProviderDependsTest::testCanDepend with data set #1 ('non-existent_file.txt')
Failed asserting that false is true.

/home/xenial/phpunittest/test.php:25

ERRORS!
Tests: 4, Assertions: 3, Errors: 1, Failures: 2.

使用@depends时,PHPUnit不会跳过@dataProvider错误测试

来自their docs

  

注意

     

当测试依赖于使用数据提供程序的测试时,依赖测试将在至少一个数据集所依赖的测试成功时执行。

如果依赖测试中提供的数据的任何部分导致错误,我想一起跳过一些测试。有没有办法解决这个限制?

如果需要,您可以fork these files进行快速测试,或者只是克隆:

git clone https://github.com/admonkey/phpunittest.git

2 个答案:

答案 0 :(得分:2)

也许这就是你期望的行为:

<?php

class DataProviderDependsTest extends PHPUnit_Framework_TestCase
{
    protected static $failed = false;

    public function getDataProvider() {
        return [
            ['real_file.txt'],
            ['non-existent_file.txt'],
        ];
    }

    /**
     * @dataProvider getDataProvider
     */
    public function testCanBeDependedOn($data) {
        try {
            $actual = file_get_contents($data);
            self::assertSame('expected', $actual);
        } catch(Exception $e) {
            self::$failed = true;
            throw $e;
        }
    }

    /**
     * @dataProvider getDataProvider
     * @depends testCanBeDependedOn
     */
    public function testCanDepend($data) {
        if (self::$failed) {
            self::markTestSkipped('testCanBeDependedOn failed');
        }
        self::assertTrue(true);
    }
}   

答案 1 :(得分:0)

很抱歉,这个答案并没有真正解决您的问题,因为您需要在数据提供程序中至少有一个传递记录才能运行基于@depends的测试。 @iRas的答案看起来像你想做的那样。

我没有删除这个答案,因为它仍然可以向其他人提供一些信息。

@depends没有执行您期望的功能。如果另一个失败,这并不意味着不运行测试。

From the Manual for @depends

  

PHPUnit支持在测试方法之间声明显式依赖关系。这种依赖关系不定义测试方法的执行顺序,但它们允许生产者返回测试夹具的实例并将其传递给依赖的消费者。 Example 2.2展示了如何使用@depends批注来表示测试方法之间的依赖关系。

     

有关更多详细信息,请参阅“测试依赖关系”一节。

这更多用于在测试函数之间传递数据,而不是用于确保在另一个测试失败时不运行一组测试。

Sample Test in Documentation

<?php
use PHPUnit\Framework\TestCase;

class StackTest extends TestCase
{
    public function testEmpty()
    {
        $stack = [];
        $this->assertEmpty($stack);

        return $stack;
    }

    /**
     * @depends testEmpty
     */
    public function testPush(array $stack)
    {
        array_push($stack, 'foo');
        $this->assertEquals('foo', $stack[count($stack)-1]);
        $this->assertNotEmpty($stack);

        return $stack;
    }

    /**
     * @depends testPush
     */
    public function testPop(array $stack)
    {
        $this->assertEquals('foo', array_pop($stack));
        $this->assertEmpty($stack);
    }
}
?>

在测试中,返回testEmpty()的$ stack,并将其传递给testPush。这意味着定义了testPush中的$ stack并且是一个空数组,而不是undefined。

理想情况下,您的测试不应该依赖于一个或另一个传递,并且是原子的,以指示功能是否有效,以帮助在代码中发现问题。如果一个测试以不期望的方式更改数据,那么基于测试传递的更多依赖性会导致大量错误,然后所有后续测试都会检查数据是否会失败,这实际上并不是您应该如何构建测试。测试良好的条件,测试失败,但是在通过和失败的测试之间没有硬依赖性。