我一直在尋找在Yii應用開發中使用TDD的最佳方式。現在大多數Web應用都由一個前端API層(通常爲JSON)組成,以向服務器和後端提供異步調用。就我而言,在這個應用程序中最常用的測試是單元測試和功能測試。後者在指南和書籍中使用最廣泛的PHPUnit + Selenium,但Behat + Mink看起來也很酷(但我還沒有真正有信心)在Yii應用中使用Restful Api的TDD最佳實踐
如果您曾經使用過使用瀏覽器的功能測試像Selenium),你知道越少你必須運行他們越好,你的感覺。這導致它們更慢,更難維護,並且有時(比如使用JS SDK的彈出式FB登錄)是痛苦的。
當使用單個網頁應用程序時,我關心測試我的apis的JSON輸出。我想用類似單元測試的方法來測試這些功能,以便更快地測試,以便於維護。考慮到我的控制器的大部分操作都可用於使用accessControl過濾器的僅記錄用戶,我想知道如何讓我的測試正常運行。
在這個時刻,我認爲有兩個方法來完成對所需enpoint得到JSON這
- 使用捲曲直接調用
- 控制器的功能
在第一個場景我可以使用fixtures,但是我沒有辦法模擬CWebUser類(模擬一個已記錄的用戶),當cUrl出現時使用Apache,它被我的CWebApplication的一個實例執行,它不是由PHPUnit執行的實例。我可以通過將所有API調用無狀態來消除此問題,並因此刪除accessControl過濾器。
在第二個中,我發現模擬CWebUser類的唯一方法是在我正在執行的測試類中覆蓋它。這種方法支付,直到我不需要測試需要不同類型用戶的用例,並且我無法在運行時(或在安裝時)更改我的webuser模擬。我發現模擬我的web用戶的唯一方法是你可以在下面找到的,這導致$ this-> getMock('WebUser')不會影響配置文件中定義的CWebApplication的WebUser(只讀)單例。
又來了一個具體的例子:
class UserControllerTest extends CDbTestCase
{
public $fixtures=array(
/* NEEDED FIXTURES*/
);
public function testUserCanGetFavouriteStore() {
$controller = new UserController(1);
$result = json_decode($controller->actionAjaxGetFavStore());
$this->assertInternalType('array', $result->data);
$model = $result->data[0];
$this->assertEquals($model->name, "Nome dello Store");
}
}
class WebUser extends CWebUser {
public function getId() {
return 1;
}
public function getIsGuest() {
return false;
}
};
我在想,如果能或者通過API密鑰或用戶/密碼組合與API接口進行身份驗證,可能是有用的。 如果我轉向幾乎無狀態的API集成,這很好,但是大多數時候我只有控制器的操作(只允許登錄用戶)返回Json數據來填充前端。
任何人都可以建議我一個更好的方法?也許這只是無用的測試這種JSON輸出?
問候
嗨Aj, 感謝您的回覆,這不能工作,因爲只要我使用標準的Cwebuser-> login()方法應用程序嘗試在會話吐出數據寫入標準輸出內容,這使得phpunit引發錯誤。 –