【问题标题】:Why does my PHPUnit Fixtures Stack test is not working properly?为什么我的 PHPUnit Fixtures Stack 测试无法正常工作?
【发布时间】:2015-09-14 19:34:51
【问题描述】:

我一直在阅读this 手册,但我不明白为什么 $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 查看值。这是我不明白的另一件事。

【问题讨论】:

    标签: php phpunit fixtures


    【解决方案1】:

    问题是:

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

    对于第一个问题,您可以使用setUpBeforeClass 方法。来自doc

    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'));
        }
    }
    

    希望有帮助

    【讨论】:

      【解决方案2】:

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

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

      (您还假设测试类中的方法以与编写它们的顺序相同的顺序运行,但不一定如此。大多数情况下它们确实以相同的顺序运行,但你不能依赖它。)

      【讨论】:

      • 知道了!你是对的。但是让我们假设我所做的不会杀死人类。那么,为什么手册有效但我的代码无效?
      • 我假设您指的是示例 4.1。仔细查看每个方法中实际发生的情况,您会发现每个测试都假设$stack 属性一开始是空的,这就是在每次测试之前调用setUp() 方法会发生的情况。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-20
      • 2021-12-30
      • 2020-06-27
      • 2021-04-03
      相关资源
      最近更新 更多