PHPUnit提供程序不使用依赖项

时间:2010-08-14 18:26:43

标签: php phpunit

我正在使用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...
        );
      }
    }

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

3 个答案:

答案 0 :(得分:3)

由于这个问题已经有2天了,我试一试:

它似乎不像你想要的那样工作。

@depends只查看提供名称的测试是否已运行并获得结果。它甚至不知道或关心所述测试的@annotations。

我猜(没有深入挖掘phpunit源代码100%确定)@depends的测试在内部运行为“测试组”,而不是单个测试,因此没有测试名为“testEmpty”,依赖失败。

所以提供一个解决方法我现在唯一能想到的就是直接调用那些“子测试”。

<?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) { ... }

希望有助于或至少激励其他人回答;)

答案 1 :(得分: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 ) );
    }

仍然很hacky,但可能比在另一个测试中调用下一个测试函数稍微少一些。

答案 2 :(得分:0)

如果测试有数据提供者,则提供的所有数据都将被输入此测试。只有这样才能运行下一个测试,这可能取决于第一次测试是否成功。未完成的是提供给第一次测试的所有数据也被送到第二次测试。

@dataProvider优先于@depends。测试可以依赖于完全测试其提供的所有数据的另一个测试,但它不会为自己获取此数据。要得到这样的东西,你必须将所有相关测试组合成一个函数。

另一方面,这样的测试设置可能首先不明显,但测试应该易于理解。考虑重构测试。