为什么我的PHPUnit fixture堆栈测试不能正常工作


Why does my PHPUnit Fixtures Stack test is not working properly?

我一直在阅读这个手册,但是我不明白为什么$stack在每个测试函数之后会丢失值。

下面是我的代码:

require_once BASE . 'Transaction.php';
class TransactionTest extends PHPUnit_Framework_TestCase
{
    protected $stack;
    protected function setUp()
    {
        Database::getInstance()->connect();
        $this->stack = new Transaction(123456789);
    }
    public function testInsert()
    {
        $data['name'] = 'Omega';
        $this->stack->set($data);
        $this->assertTrue($this->stack->save());
    }
    public function testUpdate()
    {
        $object = PHPUnitReflectionClass::getInstance($this->stack);
        $this->assertEquals(array('name' , 'Omega'), $object->getProperty('name'));
    }
}

在"testUpdate"函数中,我没有名称。

如果我只是复制所有的PHPUnit示例,所有的测试将完美地运行,但我无法看到在下一个函数中使用var_dump的值。这是另一个我不明白的地方

问题是:

  1. 在每个测试方法调用之前调用setup方法;
  2. 你的测试是相互依赖的。

对于第一个问题,可以使用setUpBeforeClass方法。来自文档:

setUp()和tearDown()模板方法为每个测试运行一次方法(以及在新的实例上)。

此外,还有setUpBeforeClass()和tearDownAfterClass()模板方法在运行测试用例类的第一个测试之前调用以及在运行测试用例类的最后一个测试之后。

对于第二个问题,让测试相互依赖是一个不好的做法,但是PHPUnit支持显式声明测试方法之间的依赖关系,所以你可以使用@depends注释来表达依赖关系:如果一个测试失败,另一个测试将不执行。

所以你的测试类可以是,例如:
require_once BASE . 'Transaction.php';
class TransactionTest extends PHPUnit_Framework_TestCase
{
    protected static $stack;
     public static function setUpBeforeClass()
    {
        Database::getInstance()->connect();
        $this->stack = new Transaction(123456789);
    }
    public function testInsert()
    {
        $data['name'] = 'Omega';
        $this->stack->set($data);
        $this->assertTrue($this->stack->save());
    }

   /**
    * @depends testInsert
    */
    public function testUpdate()
    {
        $object = PHPUnitReflectionClass::getInstance($this->stack);
        $this->assertEquals(array('name' , 'Omega'), $object->getProperty('name'));
    }
}

希望对您有所帮助

单元测试不应该依赖于其他测试,这被认为是不好的做法。单元测试的要点在于,它们运行在一个受控和隔离的环境中。setUp()tearDown()方法分别在每个测试方法之前和之后调用。因此,您的$stack属性在每次测试之前都会被覆盖。您所链接的文档(示例4.1下面)也指出了这一点:

setUp()tearDown()模板方法对测试用例类的每个测试方法(并且在新实例上)运行一次。

(您还假设测试类中的方法按照编写的顺序运行,但事实并非如此。大多数情况下,它们确实以相同的顺序运行,但您不能依赖于它。