2017-02-17 7 views
1

Symfony2에서 프로젝트의 기능 테스트를 작성하려고합니다. 사용자가 페이지에 액세스하여 양식을 작성하여 제출할 수 있는지 테스트하고 싶습니다. 테스트 전의 상태로 데이터베이스를 롤백하는 방법을 찾으려고합니다. https://gist.github.com/Vp3n/5472509에서 WebTestCase를 확장하고 setUp 및 tearDown 메소드를 오버로드 할 때 weakly로 수정 된 도우미 클래스를 발견했습니다. 는 여기가 작동 만들려고 노력하기 위해 한 개조이다 : 나는 테스트를 실행하면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) 

? 그것은 심지어 최선의 관행입니까? 어떤 도움을 주시면 감사하겠습니다 :)

편집

이 나를 위해 일한 :

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과 함께 한 번 이상 요청 하시겠습니까? 그렇다면 요청이 한 번 수행 된 후 클라이언트가 커널을 종료하는 것이 문제 일 수 있습니다. 하지만 당신은 $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'); 
} 
나는이 번들 사용하는 것이 좋습니다
+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