PHPUnit提供器无法与依赖项配合使用

6

我正在使用PHPUnit 3.4.9,但是在使用@depends注释时遇到了一些问题。它像例子中一样工作,但是当生产者依赖于提供者时会出现问题。我不知道这是否应该正常工作,但我的代码基本上是这种形式:

<?php
    class StackTest extends PHPUnit_Framework_TestCase
    {
      /**
       * @dataProvider provider
       */
      public function testEmpty ($data)
      {
        $stack = array();
        $this->assertTrue(empty($stack));

        return $stack;
      }

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

        return $stack;
      }

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

      public function provider ()
      {
        return array(
           // Some testing data here...
        );
      }
    }

上面的代码只是一个例子,但展示了我的代码结构。运行时,它会跳过消费者测试,就像生产者失败了一样。我期望对于提供者中的每组测试数据,生产者将使用该数据运行,并相应地运行其所有消费者。


1
从PHPUnit手册中:“当一个测试依赖于使用数据提供程序的测试时,只有在所依赖的测试至少成功一次数据集后,才会执行依赖测试。使用数据提供程序的测试结果无法注入到依赖测试中。” - Dean Or
3个回答

3

鉴于这个问题已经存在了2天,我来试一试:

它似乎不按照您的预期工作。

@depends 只是查看是否运行了指定名称的测试并获取结果。 它甚至不知道或关心该测试的 @annotations。

我猜(还没有深入挖掘phpunit源代码以确保100%),带有 @depends 的测试在内部被视为“测试组”,而不是单个测试,因此没有名为“testEmpty”的测试,@depends 就会失败。

因此,目前我能想到的唯一解决方法是直接调用这些“子测试”。

<?php
class StackTest extends PHPUnit_Framework_TestCase {
  /**
   * @dataProvider provider
   */
  public function testEmpty($data) {
    $stack = array();
    $this->assertTrue(empty($stack));
    $this->nextTestOrJustAllInOneTestcaseSaidly($stack);
    return $stack;
  }

  protected function nextTestOrJustAllInOneTestcaseSaidly($data) { ... }

希望这能帮到你,或者激励其他人来回答 ;)

感谢您的回答。在发布后不久,我通过将所有测试合并为一个测试来解决了这个问题,但我主要是想知道这是否是预期行为。无论如何,我都会采纳您的答案。 - rovaughn

2

我曾经遇到过一个与测试有关的问题,这个测试依赖于另一个测试(更具体地说是依赖于由该测试返回的数据),而这个测试使用了一个数据提供程序。

我通过将值(通常情况下我会从依赖测试中简单地返回该值)设置为静态变量来解决这个问题,然后我可以在其他测试中访问它。

<?php
class StackTest extends PHPUnit_Framework_TestCase {
    protected static $foo;

    public function provider() { ... }

    /**
     * @dataProvider provider
     */
    public function testOne( $data ) {
        self::$foo = array();
        $this->assertTrue( empty( self::$foo ) );
    }

    /**
     * @depends testOne
     */
    public function testTwo() { 
        $this->assertTrue( empty( self::$foo ) );
    }

仍然有些粗糙,但比从一个测试中调用下一个测试要好一些。


0
如果一个测试有数据提供者,那么所有提供的数据都将被输入到该测试中。只有在第一个测试成功后,才会运行下一个测试,而下一个测试可能依赖于第一个测试的成功。但不会将所有提供给第一个测试的数据也提供给第二个测试。 @dataProvider 的优先级高于 @depends。一个测试可以依赖于另一个完全测试其所有提供的数据的测试,但它不会为自己获取这些数据。要实现这样的功能,您确实必须将所有相关测试组合成一个函数。
另一方面,这样的测试设置可能一开始并不明显,但测试应该易于理解。考虑重构测试。

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