Fixtures (基礎設施)
通常在測試裡面,我們會需要初始化我們的測試環境 (例如建立一個被測試類別的物件) ,但如果每一個測試都要做一次初始化的動作,就會非常麻煩。
雖然可以把初始化的動作包裝成一個方法,但還是需要每次都在測試一開始時手動呼叫。如果這個動作可以讓自動測試幫我們處理,就會方便很多。
setUp 方法與 tearDown 方法
PHPUnit 提供了一組協助我們初始化測試環境的方法,即 setUp 方法與 tearDown 方法。而在 setUp 方法 初始化,以供所有測試共用的物件或變數,則稱為 fixture 。
在 setUp 方法中,會將 fixture 初始化,讓每個測試都可以使用 fixture 最初的狀態。而在 tearDown 方法中,一般是會將 fixture 消滅,以釋出它所佔用的記憶體,否則就得靠不確定何時會執行的 GC (垃圾收集) 。
修改測試
以下程式為引入 fixture 後的寫法:
<?php
/* tests/CartTest.php */
require __DIR__ . '/../Cart.php';
class CartTest extends PHPUnit_Framework_TestCase
{
private $cart = null;
public function setUp()
{
$this->cart = new Cart();
}
public function tearDown()
{
$this->cart = null;
}
/**
* @dataProvider provider
* @group update
*/
public function testUpdateQuantitiesAndGetTotal($quantities, $expected)
{
$this->cart->updateQuantities($quantities);
$this->assertEquals($expected, $this->cart->getTotal());
}
// ...
/**
* @group update
* @group exception
*/
public function testUpdateQuantitiesWithException()
{
$this->setExpectedException('CartException');
$quantities = [ -1, 0, 0, 0, 0, 0 ];
$this->cart->updateQuantities($quantities); // 預期會產生一個 Exception
}
/**
* @group get
*/
public function testGetProducts()
{
$products = $this->cart->getProducts();
$this->assertEquals(6, count($products));
$this->assertEquals(0, $products[3]['quantity']);
}
}
主要改變有:
加入一個 fixture ,即私有屬性
$cart。加入
setUp與tearDown兩個方法;setUp方法負責初始化 fixture ,將它設定為Cart類別的物件實體;而tearDown方法則清除 fixture 所佔用的記憶體。將原有測試中的
$cart = new Cart();移除,並將$cart改為$this->cart。
執行順序
每個測試方法執行之前,都會先執行 setUp 方法;而結束之後,則會執行 tearDown 方法。以此例來說,順序如下:
setUptestUpdateQuantitiesAndGetTotaltearDownsetUptestUpdateQuantitiesAndGetTotaltearDownsetUptestUpdateQuantitiesWithExceptiontearDownsetUptestGetProductstearDown
官方手冊參考
練習
解釋為什麼
$this->cart可以在每個測試中使用?思考看看為什麼每次執行測試前,都要重新初始化 fixture ?