2017-02-17 14 views
1

私はsymfony2で自分のプロジェクトの機能テストを書こうとしています。ユーザーがページにアクセスしてフォームに記入して送信できるかどうかをテストしたいと思います。 私は、テストの前の状態にデータベースをロールバックする方法を見つけようとしています。 WebTestCaseを拡張し、setUpメソッドとtearDownメソッドをオーバーロードするhttps://gist.github.com/Vp3n/5472509でヘルパークラスIが若干修正されました。 は、ここで私はそれが動作するためにしようとするためにやった改造されている:私はテストを実行するとsymfony2で機能テストを行うときにトランザクションをロールバックする方法

/** 
* 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) 

は私が間違って何をしているのですか?それはベストプラクティスですか?任意の助けをいただければ幸いです:)

EDIT

これは私の仕事:

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

}あなたは

別のオプションのテストのために献身テスト・データベースを使用することができ

答えて

3

Clientで複数のリクエストを行っていますか?そのような場合は、1回のリクエストが実行された後にクライアントがカーネルをシャットダウンするという問題があります。

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

遅く返事を申し訳ありません。実際問題は、各テスト間でカーネルがリセットされたためにトランザクションが共有されていないことでした。したがって、disableReboot()はsetAutoCommit(false)とともにトリックを作りました。あなたの返信と答えをありがとう。 – EtienneDh

1

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 
     - \AppBundle\Helper\Unit 
+0

ありがとう、私はこれを見ていきます。 Altho私はこのプロジェクトのために最初の場所で許可されていないバンドルを使用することが許可されているか分からない – EtienneDh

2

私はこのバンドルを使用することをお勧めします:https://packagist.org/packages/dama/doctrine-test-bundle

セットアップが非常に簡単にそのロールバックされます任意のデータベースが自動的に変更された後、しかし、あなたは$this->client->disableReboot()でだから、このスニペットスニペットは冪等する必要があることを無効にすることができますあらゆる単一のテストケース。カスタムを実装する必要はありません。

関連する問題