定義 Fixtures

自動測試需要被執行很多次。為了確保測試過程是可以重複的,我們很想要在一些可知的狀態下進行測試,這個狀態我們稱之為 Fixtures。舉個例子,在一個部落格應用程式中測試文章建立功能,每次當我們進行測試時, 與文章相關的資料表(例如:Post 資料表、Comment 資料表)應該被恢復到一個特定的狀態下。PHPUnit 檔案 已詳細地描述了一個廣泛 Fixture 設定。 而本節主要介紹怎樣像剛才描述的例子那樣構建資料庫 Fixture。

設置構建資料庫的 Fixture,恐怕是以資料庫為後端支援的應用程式最耗時的部分之一。Yii 引進的 CBbFixtureManager 應用程式元件可以有效的減輕這一問題。當進行一組測試的時候,它基本上會做以下這些事情:

請按照下述方法使用我們在 應用程式配置 中配置的 CDbFixtureManager.

return array(
    'components'=>array(
        'fixture'=>array(
            'class'=>'system.test.CDbFixtureManager',
        ),
    ),
);

然後我們在目錄 protected/tests/fixtures 下提供一個 Fixture 資料,這個目錄可以通過配置應用程式配置檔案中的 CDbFixtureManager::basePath 屬性指定為其他目錄。Fixture 資料是由多個稱之為 Fixture 檔案的 PHP 檔案組合而成。每個 Fixture 檔案返回一個陣列,代表資料的一個特定資料表的初始列。檔案名和資料表名相同。以下則是將 Post 表的 Fixture 資料儲存於名為 Post.php 檔案裡的例子。

<?php
return array(
    'sample1'=>array(
        'title'=>'test post 1',
        'content'=>'test post content 1',
        'createTime'=>1230952187,
        'authorId'=>1,
    ),
    'sample2'=>array(
        'title'=>'test post 2',
        'content'=>'test post content 2',
        'createTime'=>1230952287,
        'authorId'=>1,
    ),
);

正如我們所見,上面返回了兩列資料,每一列都表示一個陣列,其鍵是表的字串名,其值則是對應的字串值。每列的索引都是稱之為列別名的字串(例如:simple1simple2)。稍後當我們撰寫測試腳本的時候,我們可以方便地通過它的別名調用這列資料。我們將在下節中詳細的介紹這個。

你也許注意到了我們並未在上述 Fixture 中指定 id 字串的值。這是因為 id 字串已經被定義為自動遞增主鍵了,它的值也會在我們插入新資料的時候自動產生。

CDbFixtureManager 第一次被引用時,它會仔細檢查所有的 Fixture 檔案然後使用他們重置對應的資料表。它通過清空資料表,重置資料表主鍵的自動遞增序列值,然後插入來自 Fixture 檔案的資料列到資料表中來重置資料表.

有時候,我們可能不想在一套測試前重置 Fixture 檔案裡描述的每一個表,因為重置太多的 Fixture 檔案可能需要很多時間。這種情況下,我們可以寫一個 PHP 腳本來定制這個初始化過程。這個腳本應該被儲存在存放 Fixture 檔案的目錄下,並命名為 init.php。當 CDbFixtureManager 檢測到了這個腳本的存在,它將執行這個腳本而不是重置每一個資料表。

不喜歡使用預設方式來重置資料表也是可以的,例如:清空資料表然後插入 Fixture 資料,如果是這種情況,我們可以為指定的 Fixture 檔案撰寫一個初始化腳本。這個腳本必須名稱為資料表名+.init.php。例如:Post 資料表的初始化腳本檔案就是 Post.init.php。當 CDbFixtureManager 發現了這個腳本,它將執行這個腳本而不是採用預設的方式去重置該資料表。

Tip: 太多的 Fixture 檔案大大延長了測試時間。因此,你應該只為那些在測試中資料會發生變化的表提供 Fixture 檔案。那些做為查找服務的資料表不會改變,因此不需要 Fixture 檔案。

接下來兩節,我們將談到如何在單元測試和功能測試中使用被 CDbFixtureManager 管理的 Fixture。

$Id$