我一直在寻找在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引发错误。 –