Zend_Test_PHPUnit(日本語)Zend_Test_PHPUnit は MVC アプリケーション向けのテストケースを用意します。 さまざまな責務に対応したテスト用のアサーションが含まれています。 実際に何ができるのかを知るには、 サンプルを見ていただくのが一番でしょう。 Example #1 Application Login TestCase のサンプル 以下に示すのは UserController 用のシンプルなテストケースで、以下のような内容を検証します。
この例は、いくつかの前提条件のもとに作成されています。 まず、起動時の設定のほとんどをプラグインに追い出しました。 これにより、環境設定が簡潔になったのおで テストケースの準備がしやすくなりました。 また、アプリケーションの起動処理が 1 行で書けるようになっています。 また、autoloading の設定を行うことで、 (コントローラやプラグインなどの) 適切なクラスをいちいち require することを考えなくてすむようにしています。
この例は、もう少しシンプルに書くこともできます。 ここで示したアサーションのすべてが必須というわけではなく、 単に説明のためだけに用意しているものもあるからです。 アプリケーションのテストがいかにシンプルにできるのか、 この例でご理解いただけることでしょう。 テストケースの起動Login サンプル で説明したように、すべての MVC テストケースは Zend_Test_PHPUnit_ControllerTestCase を継承しなければなりません。このクラスは PHPUnit_Framework_TestCase を継承しており、 PHPUnit が提供する仕組みやアサーションをすべて使用できます。 またそれに加えて、Zend Framework の MVC 実装に特化した scaffold 機能やアサーションもあります。
MVC アプリケーションをテストするには、まずそれを起動する必要があります。
いくつかの方法がありますが、どの方法になるかは public プロパティ
最初に、そして、おそらく最も直接的には、 単純に index.php で行うように Zend_Application インスタンスを作成します。 そして、それを $bootstrap プロパティにアサインします。 一般的に、これは setUp() で行います。 実行されるときに、 parent::setUp() を呼ぶ必要があります。
次に、このプロパティでファイルを指定できます。 そうすると、そのファイルはフロントコントローラをディスパッチせず、 単にフロントコントローラ (とアプリケーション固有の設定) を準備するだけの役割となります。
3番目の方法として、アプリケーションを起動するための PHP コールバックを指定できます。 この方法は Login サンプル で使用しています。使用するコールバックが関数や static メソッドである場合は、クラスレベルで設定できます。
オブジェクトのインスタンスが必要な場合は、 setUp() メソッドを利用することを推奨します。
parent::setUp(); に注目しましょう。 これは必須です。とうのも、Zend_Test_PHPUnit_ControllerTestCase の setUp() メソッドが残りの起動処理 (コールバックの呼び出しも含む) を実行するからです。 通常、 setUp() メソッドは次のようにアプリケーションを起動します。 まずクリーンな環境を読み込んでリクエストの状態を初期化し、 プラグインやヘルパーをすべてリセットし、 フロントコントローラをリセットして リクエストオブジェクトとレスポンスオブジェクトを新しく作成します。 それが終わったら、$bootstrap で指定したファイルを include() するか、 あるいは指定したコールバックを呼び出します。 テストの起動処理は、可能な限りそのアプリケーションの起動処理と同じになるようにしています。 しかし、いくつかの制約もあります。
アプリケーションが起動したら、 いよいよテストを作り始めることができます。 コントローラおよび MVC アプリケーションのテスト起動用の設定を済ませたら、テストの開始です。 テストの方法は PHPUnit テストスイートによるものとほぼ同じですが、 ちょっとした違いがいくつかあります。 まず、テストケースの dispatch() メソッドを用いてテストの URL をディスパッチしなければなりません。
しかし、時にはこれ以外の情報 (GET 変数や POST 変数、 COOKIE 情報など) が必要になることもあります。 これらの情報をリクエストに含めることもできます。
リクエストが準備できたので、次はアサーションを作成してみましょう。 コントローラのテストと Redirector アクションヘルパーImportant
Redirect アクションヘルパーは、 gotoAndExit() メソッドを使うときに exit() ステートメントを発行し、このメソッドを使用するコントローラーに対するテストを全て停止させます。 アプリケーションのテスト容易性を考慮して、 リダイレクタではこのメソッドを使わないようにしましょう。 その性質上、リダイレクタアクションヘルパープラグインは リダイレクトしたあと処理を終了します。 Because you cannot test parts of an application that issue exit calls Zend_Test_PHPUnit_ControllerTestCase automatically disables the exit part of the redirector as it can cause test behavior to differ from the real application. To ensure your controllers can be properly tested, please make use of the redirector when you need to redirect the user to a different page:
Important
アプリケーションによっては、これだけでは不十分かもしれません。さらに preDispatch() あるいは postDispatch() といったロジックを実行するかもしれないからです。 現状の Zend Test では、これらをうまく処理することはできません。 アサーション注意:このドキュメントでは、英語版のリビジョン 22761 の更新内容をスキップしています。 アサーションは、ユニットテストの肝となるものです。 この機能を使うことで、期待する結果と実際の結果が一致することを確かめるのです。 Zend_Test_PHPUnit_ControllerTestCase では数多くのアサーションを用意しており、 MVC アプリケーションやコントローラのテストをよりシンプルにできるようにしています。 CSS セレクタアサーションCSS セレクタを使うと、 レスポンスの中身に何らかの結果が入っていることを簡単に検証できます。 また、Javascript の UI や AJAX との統合も簡単に行えます。 大半の JS ツールキットは、 CSS セレクタ形式で DOM 要素を取得するための仕組みを持っています。 それと同じ構文で使用できるのです。 この機能は Zend_Dom_Query を用いて実装されており、'Query' アサーションに統合されています。 個々のアサーションの最初の引数に CSS セレクタを指定し、 アサーションの型に応じてオプション引数やエラーメッセージも指定します。 CSS セレクタの書き方の規則については、Zend_Dom_Query の操作方法の章 を参照ください。Query アサーションには次のようなものがあります。
さらに、上であげたそれぞれに対する否定のアサーションを行う 'Not' 系のメソッドが存在します。 assertNotQuery()、 assertNotQueryContentContains()、 assertNotQueryContentRegex() そして assertNotQueryCount() です (min および max については対応するメソッドは存在しませんが、 それは自明なことだからです)。 XPath アサーションCSS セレクタよりも XPath のほうが使いやすいという開発者もいることでしょう。 そこで、 Query アサーション のすべてのメソッドに対して、同等の動作をする XPath 版のメソッドを用意しています。
リダイレクトアサーションアクションがリダイレクトを行うこともよくあります。 リダイレクト先をたどらなくても、 Zend_Test_PHPUnit_ControllerTestCase のさまざまなアサーションでそれをテストできます。
レスポンスヘッダアサーションリダイレクトヘッダのチェックだけでなく、 特定の HTTP のレスポンスコードやヘッダのチェックが必要になることもあります。 たとえば「アクションの結果のレスポンスが 404 か 500 のいずれかであること」 「JSON レスポンスに適切な Content-Type ヘッダが設定されていること」 などです。次のようなアサーションが使用できます。
さらに、上であげたそれぞれに対する否定のアサーションを行う 'Not' 系のメソッドが存在します。 リクエストアサーション最後に実行されたアクションやコントローラ、 そしてモジュールについてのアサーションを行えると便利です。 さらに、どのルートにマッチしたのかを確認したいこともあるでしょう。 以下のアサーションが、その手助けとなります。
そして、それぞれについて否定を表す 'Not' 系のメソッドが存在します。 例テスト環境の設定方法とアサーションの作成方法を説明しましたが、 まだまだ戦いは続きます。それでは、 実際のテストシナリオをもとにテストの方法を確認していきましょう。 Example #2 UserController のテスト ウェブサイトの一般的なタスクである、 ユーザ認証とユーザ登録について考えてみましょう。 今回の例では UserController でこれらを処理することにします。 要件は次のとおりです。
もちろんこれら以外にも別のテストも必要でしょうが、 今のところはひとまずこれだけにしておきます。 今回のアプリケーションでは、プラグイン 'Initialize' を定義してそれを routeStartup() で実行します。 これによって起動処理をオブジェクト指向でカプセル化することができ、 コールバックを提供しやすくなります。 それではまず、このクラスの基本部分を見ていきましょう。
これで、起動用コールバックを次のように作れるようになります。
ここまでできたら、テストを書くことができます。 しかし、ユーザがログインした状態でのテストはどのように書けばいいでしょう? 簡単な方法は、アプリケーションのロジックを利用する方法です。 resetRequest() メソッドや resetResponse() メソッドを使ってちょっとした細工を行い、 別のリクエストをディスパッチさせます。
ではテストを書いてみましょう。
これらは簡潔なものであり、大半は実際の中身までは見ていないことに注意しましょう。 その代わりに、レスポンスコードやヘッダ、そして DOM ノードを見ています。 これにより、期待通りの構造になっているかどうかを検証できるようになり、 新たなコンテンツが追加されるたびにテストを実行しなおすことが避けられます。 ドキュメントの構造を使用してテストを行なっていることに注目しましょう。 たとえば最後のテストでは、"errors" というクラスが指定されているノードをフォームから探しました。 これにより、単にフォームの検証エラーが発生したかどうかだけを確認することができ、 どんなエラーが発生したのかという中身までは気にしなくてすむのです。 このアプリケーションでは、データベースを使うことがあるかもしれません。 そんな場合は、何らかの scaffold を使用してデータベースの初期状態を作成し、 テスト用の設定を行うという作業が各テストの最初に発生します。 PHPUnit にはそのための機能が既に用意されています。 » PHPUnit のドキュメントを参照ください。 テスト時と実運用時には別のデータベースを使用することを推奨します。 また、特に (ファイルあるいはインメモリ形式の) SQLite を使うことを推奨します。どちらも別のサーバを必要とせず、 大半の SQL 構文を使用できます。
|