使用Symfony2进行功能测试时,如何回滚交易



我正在尝试在Symfony2中为项目编写功能测试。我想测试用户是否可以访问页面,填写表格并提交。我正在尝试找到一种将数据库滚动到测试之前的状态的方法。我在https://gist.github.com/vp3n/5472509上找到了一个辅助类,我在https://gist.github.com/v3n/5472509上进行了修改,该类别扩展了WebTestcase和Overload设置和拆卸方法。这是我为试图使其有效的mods:

 /**
 * Before each test we start a new transaction
 * everything done in the test will be canceled ensuring isolation et speed
 */
protected function setUp()
{
    parent::setUp();
    $this->client = $this->createClient();
    $this->em = static::$kernel->getContainer()
        ->get('doctrine')
        ->getManager();
    $this->em->getConnection()->beginTransaction();
    $this->em->getConnection()->setAutoCommit(false);
}
/**
 * After each test, a rollback reset the state of 
 * the database
 */
protected function tearDown()
{
    parent::tearDown();
    if($this->em->getConnection()->isTransactionActive()){
        echo 'existing transactions';
        $this->em->getConnection()->rollback();
        $this->em->close();
    }
}

当我运行测试时,它确认现有交易,但回滚失败并持续进行修改。

测试日志:

Runtime:       PHP 5.6.15
.existing transactions.      2/2 (100%)existing transactions                                                                                      
Time: 5.47 seconds, Memory: 24.50MB
OK (2 tests, 5 assertions)

我在做什么错?这是最好的做法吗?

编辑

这对我有用:

abstract class DatabaseWebTest extends WebTestCase {
    /**
     * helper to acccess EntityManager
     */
    protected $em;
    /**
     * Helper to access test Client
     */
    protected $client;
    /**
     * Before each test we start a new transaction
     * everything done in the test will be canceled ensuring isolation et speed
     */
    protected function setUp()
    {
        parent::setUp();
        
        $this->client = $this->createClient(['environment' => 'test'], array(
            'PHP_AUTH_USER' => 'user',
            'PHP_AUTH_PW'   => 'password',
            ));
        $this->client->disableReboot();
        $this->em = $this->client->getContainer()->get('doctrine.orm.entity_manager');        
        $this->em->beginTransaction();
        $this->em->getConnection()->setAutoCommit(false);
    }
    /**
     * After each test, a rollback reset the state of 
     * the database
     */
    protected function tearDown()
    {
        parent::tearDown();
        if($this->em->getConnection()->isTransactionActive()) {
            $this->em->rollback();
        }        
    }
}

您是否使用Client进行多个请求?如果是这样,您可能会出现的问题是,在执行一个请求后,客户端将关闭内核。但是您可以使用$this->client->disableReboot()禁用此片段,以便该代码片段应为基础:

public function setUp()
{
    $this->client = $this->createClient(['environment' => 'test']);
    $this->client->disableReboot();
    $this->em = $this->client->getContainer()->get('doctrine.orm.entity_manager');
    $this->em->beginTransaction();
}
public function tearDown()
{
    $this->em->rollback();
}
public function testCreateNewEntity()
{
    $this->client->request('GET', '/create/entity/form');
    $this->client->request('POST', '/create/entity/unique/123');
}

我建议使用此捆绑包:https://packagist.org/packages/dama/doctrine-test-bundle

它非常易于设置,并将在每个测试箱后自动更改任何数据库。无需实施任何自定义的事情。

您可以使用奉献测试数据库进行测试

另一个选项是使用CodeCeption。这是一个与Symfony一起使用的单元测试捆绑包。如果使用此功能,则可以将其配置为使用测试数据库,然后在每个测试周期后"清理"。
yaml configuartion做的示例就是这样,是 cleanup: true可以做你想要的;

class_name: UnitTester
modules:
    enabled:
        - Asserts
        - Symfony2:
            app_path: '../../app'
            var_path: '../../app'
            environment: 'test'
        - Doctrine2:
            depends: Symfony2
            cleanup: true
        - AppBundleHelperUnit

最新更新