如何使用Symfony2和Doctrine回滚Behat 3功能测试中的提交?

stu*_*zzo 12 bdd symfony doctrine-orm behat

作为标题,我的目标是回滚在Behat功能测试期间做出的任何提交.我检查这个答案非常相似,但它是从两年前开始,似乎不可能做到.

也许现在有了Behat 3,这是可能的.

我知道使用PHPUnit,我可以使用startUp和tearDown方法达到类似的效果.

我尝试使用@BeforeScenario和@AfterScenario注释来启动和回滚事务挂钩,但似乎behat和应用程序不共享实体管理器的相同实例.

一些建议吗?

谢谢.


UPDATE

谢谢大家的意见.这里有一些新的考虑:

  • LOAD FIXTURES:是的,它有效.我可以在测试开始之前运行灯具,但是问题(我的错误,不提它)是灯具有时需要几分钟才能加载,在测试开始前等待10分钟或更长时间是令人讨厌的.

  • BEGIN/ROLLBACK TRANSACTION:它既可以使用也可以使用.我没有收到任何错误,但测试期间写入的数据在结束时仍在我的数据库中.我在一个方法中添加了第一个标记为@BeforeScenario的方法,后者在一个用@AfterScenario标记的方法中

$this->kernel->getContainer()
    ->get('doctrine.orm.entity_manager')
    ->getConnection()
    ->beginTransaction();

$this->kernel->getContainer()
   ->get('doctrine.orm.entity_manager')
   ->getConnection()
   ->rollBack();
  • SAVEPOINT:我认为这正是我所需要的,但我的数据仍然存在.我尝试在@BeforeScenario方法中添加保存点的创建,并在@AfterScenario方法上回滚
public function gatherContexts(BeforeScenarioScope $scope) {
    $environment = $scope->getEnvironment();
    $connection = $this->kernel->getContainer()->get('doctrine.orm.entity_manager')->getConnection();
    $connection->beginTransaction();
    $connection->createSavepoint('tests');
}

public function rollback(AfterScenarioScope $scope) {
    $connection = $this->kernel->getContainer()->get('doctrine.orm.entity_manager')->getConnection();
    $connection->rollbackSavepoint('tests');
}

所有这些测试都用于测试我的API REST项目.经过这些考虑后,我认为Behat和我的应用程序不共享实体管理器的相同实例.您是否能够在测试期间在测试和项目之间共享相同的实例?

小智 7

如果您的上下文实现了KernelAwareContext,那么在@BeforeScenario和@AfterScenario注释方法中,您可以执行

$this->kernel->getContainer()->getDoctrine()->getConnection()->beginTransaction();
$this->kernel->getContainer()->getDoctrine()->getConnection()->rollBack();
Run Code Online (Sandbox Code Playgroud)

假设您只有一个连接并且由em使用它.

您也可以尝试$connection->setRollbackOnly()但请记住,它将极大地依赖于您的底层数据库.Mysql可能会在很多情况下自动提交你没想到的.

最后还有$connection->createSavepoint('savePointName')$connection->rollbackSavepoint('savePointName')

这是我的想法,因此可能需要一些调整.

  • 我是否建议您使用一些示例代码更新此答案,以显示开始事务和/或回滚事务的完整注释方法? (3认同)

Ale*_*ant 0

有了setUp方法,你就可以开始交易了。tearDown如果两个方法调用之间没有提交,您可以在方法中回滚它。

即使回滚查询,在生产数据库上启动测试也是非常危险的。这是使用数据夹具初始化数据库测试的更好方法。如果你做不到(我认为是这样),你想用生产数据进行测试。使用doctrine:migrations(或doctrine:schema:create) 将生产数据库架构复制到开发环境中,并添加脚本来复制数据。