私は、Yii アプリ開発で TDD を使用する最良の方法を常に探しています。現在、ほとんどの Web アプリは、フロントエンドの API レイヤー (通常は JSON) で構成され、サーバーとバックエンドへの非同期呼び出しを提供します。私の側では、このアプリで最もよく使用されるテストは、単体テストと機能テストです。後者は PHPUnit + Selenium を活用したガイドや書籍で最も広く示されていますが、Behat + Mink も非常にクールに思えます (ただし、まだあまり自信がありません)。
ブラウザー (Selenium など) を使用する機能テストを使用したことがある場合は、それらを実行する必要が少ないほど、気分が良くなることを知っています。これにより、速度が遅くなり、保守が難しくなり、時には (JS SDK を使用したポップアップ FB ログインのように) 苦痛を伴います。
単一の Web ページ アプリケーションを操作するときは、自分の API の JSON 出力をテストすることに関心があります。これらの機能を単体テストのようなアプローチでテストして、保守が容易な高速テストを実現したいと考えています。私のコントローラーのアクションのほとんどは、accessControl フィルターを使用してログに記録されたユーザーのみが利用できることを考慮して、テストを実行するための最良の方法を考えました。
現時点では、これを達成するには2つの方法があると思います
- 目的のエンドポイントに対して cUrl を使用して、JSON を直接呼び出す
- コントローラーの機能
最初のシナリオでは、フィクスチャを使用できますが、(ログに記録されたユーザーをエミュレートするために) CWebUser クラスをモックする方法がありません。cUrl が来たときに Apache を使用すると、PHPUnit によって実行されたものではない CWebApplication のインスタンスによって実行されます。すべての API 呼び出しをステートレスにし、その結果として accessControl フィルターを削除することで、この問題を取り除くことができます。
2 番目の例では、CWebUser クラスをモックする唯一の方法は、実行中のテスト クラスでオーバーライドすることです。このアプローチは、さまざまなタイプのユーザーを必要とするユースケースをテストする必要がなくなり、実行時 (またはセットアップ時) に Web ユーザーのモックを変更する方法がなくなるまで有効です。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 出力をテストするのは無駄ではないでしょうか?
よろしくお願いします