[GENERIC] Zend_Translate:
[zend.git] / documentation / manual / ja / module_specs / Zend_Test-PHPUnit-Examples.xml
blob6d6e95fb0eeb29a111fa1714a21b82d082404ac5
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!-- Reviewed: no -->
3 <!-- EN-Revision: 20807 -->
4 <sect2 id="zend.test.phpunit.examples">
5     <title>例</title>
7     <para>
8         テスト環境の設定方法とアサーションの作成方法を説明しましたが、
9         まだまだ戦いは続きます。それでは、
10         実際のテストシナリオをもとにテストの方法を確認していきましょう。
11     </para>
13     <example id="zend.test.phpunit.examples.userController">
14         <title>UserController のテスト</title>
16         <para>
17             ウェブサイトの一般的なタスクである、
18             ユーザ認証とユーザ登録について考えてみましょう。
19             今回の例では UserController でこれらを処理することにします。
20             要件は次のとおりです。
21         </para>
23         <itemizedlist>
24             <listitem><para>
25                 ユーザがまだ認証を済ませていない場合は、
26                 どんなアクションが指定されたかにかかわらず
27                 常にコントローラのログインページにリダイレクトされる。
28             </para></listitem>
30             <listitem><para>
31                 ログインフォームのページには、
32                 ログインフォームと新規登録フォームの両方が表示される。
33             </para></listitem>
35             <listitem><para>
36                 間違った認証情報を入力すると、
37                 ログインフォームに戻る。
38             </para></listitem>
40             <listitem><para>
41                 正しい認証情報を入力すると、
42                 ユーザのプロファイルページにリダイレクトされる。
43             </para></listitem>
45             <listitem><para>
46                 プロファイルページには、そのユーザのユーザ名が表示される。
47             </para></listitem>
49             <listitem><para>
50                 認証済みのユーザがログインフォームを訪れると、
51                 そのユーザのプロファイルページにリダイレクトされる。
52             </para></listitem>
54             <listitem><para>
55                 ログアウトしたら、ログインページにリダイレクトされる。
56             </para></listitem>
58             <listitem><para>
59                 無効なデータが渡された場合は、登録に失敗する。
60             </para></listitem>
61         </itemizedlist>
63         <para>
64             もちろんこれら以外にも別のテストも必要でしょうが、
65             今のところはひとまずこれだけにしておきます。
66         </para>
68         <para>
69             今回のアプリケーションでは、プラグイン 'Initialize'
70             を定義してそれを <methodname>routeStartup()</methodname> で実行します。
71             これによって起動処理をオブジェクト指向でカプセル化することができ、
72             コールバックを提供しやすくなります。
73             それではまず、このクラスの基本部分を見ていきましょう。
74         </para>
76         <programlisting language="php"><![CDATA[
77 class Bugapp_Plugin_Initialize extends Zend_Controller_Plugin_Abstract
79     /**
80      * @var Zend_Config
81      */
82     protected static $_config;
84     /**
85      * @var string 現在の環境
86      */
87     protected $_env;
89     /**
90      * @var Zend_Controller_Front
91      */
92     protected $_front;
94     /**
95      * @var string アプリケーションのルートパス
96      */
97     protected $_root;
99     /**
100      * コンストラクタ
101      *
102      * 環境、ルートパス、設定を初期化します
103      *
104      * @param  string $env
105      * @param  string|null $root
106      * @return void
107      */
108     public function __construct($env, $root = null)
109     {
110         $this->_setEnv($env);
111         if (null === $root) {
112             $root = realpath(dirname(__FILE__) . '/../../../');
113         }
114         $this->_root = $root;
116         $this->initPhpConfig();
118         $this->_front = Zend_Controller_Front::getInstance();
119     }
121     /**
122      * ルートの開始処理
123      *
124      * @return void
125      */
126     public function routeStartup(Zend_Controller_Request_Abstract $request)
127     {
128         $this->initDb();
129         $this->initHelpers();
130         $this->initView();
131         $this->initPlugins();
132         $this->initRoutes();
133         $this->initControllers();
134     }
136     // この後にメソッド定義が続きます...
138 ]]></programlisting>
140         <para>
141             これで、起動用コールバックを次のように作れるようになります。
142         </para>
144         <programlisting language="php"><![CDATA[
145 class UserControllerTest extends Zend_Test_PHPUnit_ControllerTestCase
147     public function appBootstrap()
148     {
149         $controller = $this->getFrontController();
150         $controller->registerPlugin(
151             new Bugapp_Plugin_Initialize('development')
152         );
153     }
155     public function setUp()
156     {
157         $this->bootstrap = array($this, 'appBootstrap');
158         parent::setUp();
159     }
161     // ...
163 ]]></programlisting>
165         <para>
166             ここまでできたら、テストを書くことができます。
167             しかし、ユーザがログインした状態でのテストはどのように書けばいいでしょう?
168             簡単な方法は、アプリケーションのロジックを利用する方法です。
169             <methodname>resetRequest()</methodname> メソッドや
170             <methodname>resetResponse()</methodname> メソッドを使ってちょっとした細工を行い、
171             別のリクエストをディスパッチさせます。
172         </para>
174         <programlisting language="php"><![CDATA[
175 class UserControllerTest extends Zend_Test_PHPUnit_ControllerTestCase
177     // ...
179     public function loginUser($user, $password)
180     {
181         $this->request->setMethod('POST')
182                       ->setPost(array(
183                           'username' => $user,
184                           'password' => $password,
185                       ));
186         $this->dispatch('/user/login');
187         $this->assertRedirectTo('/user/view');
189         $this->resetRequest()
190              ->resetResponse();
192         $this->request->setPost(array());
194         // ...
195     }
197     // ...
199 ]]></programlisting>
201         <para>
202             ではテストを書いてみましょう。
203         </para>
205         <programlisting language="php"><![CDATA[
206 class UserControllerTest extends Zend_Test_PHPUnit_ControllerTestCase
208     // ...
210     public function testCallWithoutActionShouldPullFromIndexAction()
211     {
212         $this->dispatch('/user');
213         $this->assertController('user');
214         $this->assertAction('index');
215     }
217     public function testLoginFormShouldContainLoginAndRegistrationForms()
218     {
219         $this->dispatch('/user');
220         $this->assertQueryCount('form', 2);
221     }
223     public function testInvalidCredentialsShouldResultInRedisplayOfLoginForm()
224     {
225         $request = $this->getRequest();
226         $request->setMethod('POST')
227                 ->setPost(array(
228                     'username' => 'bogus',
229                     'password' => 'reallyReallyBogus',
230                 ));
231         $this->dispatch('/user/login');
232         $this->assertNotRedirect();
233         $this->assertQuery('form');
234     }
236     public function testValidLoginShouldRedirectToProfilePage()
237     {
238         $this->loginUser('foobar', 'foobar');
239     }
241     public function testAuthenticatedUserShouldHaveCustomizedProfilePage()
242     {
243         $this->loginUser('foobar', 'foobar');
244         $this->request->setMethod('GET');
245         $this->dispatch('/user/view');
246         $this->assertNotRedirect();
247         $this->assertQueryContentContains('h2', 'foobar');
248     }
250     public function
251         testAuthenticatedUsersShouldBeRedirectedToProfileWhenVisitingLogin()
252     {
253         $this->loginUser('foobar', 'foobar');
254         $this->request->setMethod('GET');
255         $this->dispatch('/user');
256         $this->assertRedirectTo('/user/view');
257     }
259     public function testUserShouldRedirectToLoginPageOnLogout()
260     {
261         $this->loginUser('foobar', 'foobar');
262         $this->request->setMethod('GET');
263         $this->dispatch('/user/logout');
264         $this->assertRedirectTo('/user');
265     }
267     public function testRegistrationShouldFailWithInvalidData()
268     {
269         $data = array(
270             'username' => 'This will not work',
271             'email'    => 'this is an invalid email',
272             'password' => 'Th1s!s!nv@l1d',
273             'passwordVerification' => 'wrong!',
274         );
275         $request = $this->getRequest();
276         $request->setMethod('POST')
277                 ->setPost($data);
278         $this->dispatch('/user/register');
279         $this->assertNotRedirect();
280         $this->assertQuery('form .errors');
281     }
283 ]]></programlisting>
285         <para>
286             これらは簡潔なものであり、大半は実際の中身までは見ていないことに注意しましょう。
287             その代わりに、レスポンスコードやヘッダ、そして DOM ノードを見ています。
288             これにより、期待通りの構造になっているかどうかを検証できるようになり、
289             新たなコンテンツが追加されるたびにテストを実行しなおすことが避けられます。
290         </para>
292         <para>
293             ドキュメントの構造を使用してテストを行なっていることに注目しましょう。
294             たとえば最後のテストでは、"errors"
295             というクラスが指定されているノードをフォームから探しました。
296             これにより、単にフォームの検証エラーが発生したかどうかだけを確認することができ、
297             どんなエラーが発生したのかという中身までは気にしなくてすむのです。
298         </para>
300         <para>
301             このアプリケーションでは、データベースを使うことがあるかもしれません。
302             そんな場合は、何らかの scaffold を使用してデータベースの初期状態を作成し、
303             テスト用の設定を行うという作業が各テストの最初に発生します。
304             PHPUnit にはそのための機能が既に用意されています。
305             <ulink
306                 url="http://www.phpunit.de/pocket_guide/3.3/ja/database.html">
307                 PHPUnit のドキュメントを参照ください</ulink>。
308             テスト時と実運用時には別のデータベースを使用することを推奨します。
309             また、特に (ファイルあるいはインメモリ形式の) SQLite
310             を使うことを推奨します。どちらも別のサーバを必要とせず、
311             大半の <acronym>SQL</acronym> 構文を使用できます。
312         </para>
313     </example>
314 </sect2>
315 <!--
316 vim:se ts=4 sw=4 et: