2017-02-17 26 views
1

我正在嘗試爲Symfony2中的項目編寫功能測試。我想測試用戶是否可以訪問頁面,填寫表單並提交。 我試圖找到一種方法將數據庫回滾到測試前的狀態。 我發現了一個輔助類,我稍微修改了https://gist.github.com/Vp3n/5472509這個擴展了WebTestCase和重載setUp和tearDown方法。 下面是我爲了做嘗試,使其工作MODS的:如何在使用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

謝謝,我會看看這個。雖然我不確定我被允許使用這個項目的第一個地方不允許使用的軟件包 – EtienneDh

相關問題