イントロダクション
Laravelはユニットテストも考慮して作られています。実際、最初からPHPUnitを含んでおり、アプリケーションにはphpunit.xml
ファイルを用意してあります。(訳注:現在はPHPUnitを取り込んでおらず、必要に応じてユーザーが読み込みます。)さらにPHPUnitに関してLaravelは、テスト時にブラウザーをシミュレートし、ビューを調査/操作できるように、SymfonyのHttpKernel、DomCrawler、BrowserKitコンポーネントを用意してあります。
サンプルのテストファイルがapp/tests
ディレクトリーに提供されています。新しいLaravelアプリケーションをインストールしたあとで、シンプルにphpunit
をコマンドラインで実行し、テストしてみてください。
テスト定義と実行
テストケースを作成するには、app/tests
ディレクトリーにファイルを作成してください。テストケースはTestCase
を拡張してください。PHPUnitを使用する時と同様にテストメソッドを定義します。
テストケース例
class FooTest extends TestCase {
public function testSomethingIsTrue()
{
$this->assertTrue(true);
}
}
アプリケーションの全テストは、端末でphpunit
コマンドを実行することにより行われます。
注意:
setUp
メソッドを定義する場合は、parent::setUp
を確実に呼び出してください。
テスト環境
テスト実行時にLaravelは自動的に設定環境をtesting
にセットします。そして、Laravelはsession
とcache
の設定ファイルをテスト環境で呼び出します。両方のドライバーはテスト環境ではarray
にセットされます。これが意味するのはデータはテストを実行している間のみ存在しているということです。必要であれば、他のテスト設定環境を自由に作成することもできます。
テストからルートを呼び出す
テストからルートを呼び出す
テストでルートを呼び出すのは簡単で、call
メソッドを使用します。
$response = $this->call('GET', 'user/profile');
$response = $this->call($method, $uri, $parameters, $files, $server, $content);
その後、Illuminate\Http\Response
オブジェクトを調べます。
$this->assertEquals('Hello World', $response->getContent());
テストからコントローラーを呼び出す
コントローラーをテストから呼び出すこともできます。
$response = $this->action('GET', 'HomeController@index');
$response = $this->action('GET', 'UserController@profile', array('user' => 1));
getContent
メソッドはレスポンスのコンテンツ文字列を評価し、リターンします。ルートがビュー('View')をリターンするときは、original
プロパティーを使用し、アクセスできます。
$view = $response->original;
$this->assertEquals('John', $view['name']);
HTTPSルートを呼び出す場合、callSecure
メソッドを使用します。
$response = $this->callSecure('GET', 'foo/bar');
注意:テスト中の
testing
環境では、ルートフィルターは無効になっています。有効にするには、Route::enableFilters()
をテストで使用してください。
DOMクローラー
コンテンツの内容を調べるために、ルートを呼び出し、DOMクローラー(Crawler)インスタンスを受け取ることも可能です。
$crawler = $this->client->request('GET', '/');
$this->assertTrue($this->client->getResponse()->isOk());
$this->assertCount(1, $crawler->filter('h1:contains("Hello World!")'));
どのようにこのクローラーを使用するかをもっと詳しく知りたい場合は公式ドキュメントを参照してください。
Facadesのモック
テストをしているとLaravelのstaticなfacadeの呼び出しのモックが必要となることが多いでしょう。例えば、次のコントローラーアクションを考えてみてください。
public function getIndex()
{
Event::fire('foo', array('name' => 'Dayle'));
return 'All done!';
}
Facadeに対しshouldReceive
メソッドを使用することで、Event
クラスの呼び出しをモックすることができます。これはMockeryのインスタンスをリターンします。
Facadeをモックする
public function testGetIndex()
{
Event::shouldReceive('fire')->once()->with('foo', array('name' => 'Dayle'));
$this->call('GET', '/');
}
注意:
Request
Facadeに対してモックは使わないでください。その代わりにテストを実行する場合は、call
メソッドに希望する入力を渡してください。
フレームワーク関連
Laravelには最初からテストを多少簡単にするために、いくつかassert
メソッドが用意されています。
レスポンスがOKであることをアサートする
public function testMethod()
{
$this->call('GET', '/');
$this->assertResponseOk();
}
レスポンス状態をアサートする
$this->assertResponseStatus(403);
レスポンスがリダイレクトであることをアサートする
$this->assertRedirectedTo('foo');
$this->assertRedirectedToRoute('route.name');
$this->assertRedirectedToAction('Controller@method');
ビューがデータをことをアサートする
public function testMethod()
{
$this->call('GET', '/');
$this->assertViewHas('name');
$this->assertViewHas('age', $value);
}
セッションにデータが存在することをアサートする
public function testMethod()
{
$this->call('GET', '/');
$this->assertSessionHas('name');
$this->assertSessionHas('age', $value);
}
セッションがエラーを持っているか、アサートする
public function testMethod()
{
$this->call('GET', '/');
$this->assertSessionHasErrors();
// 指定されたキーのエラーがセッションに存在するかアサートする
$this->assertSessionHasErrors('name');
// 複数キーのエラーがセッションに存在するかアサートする
$this->assertSessionHasErrors(array('name', 'age'));
}
直前の入力のデーターをアサートする
public function testMethod()
{
$this->call('GET', '/');
$this->assertHasOldInput();
}
ヘルパメソッド
TestCase
クラスはアプリケーションのテストを簡単にするために、いくつかのヘルパを用意しています。
テスト中でセッションを設定、フラッシュする
$this->session(['foo' => 'bar']);
$this->flushSession();
現在の認証中ユーザーをセットする
現在認証中のユーザーをセットしたい場合はbe
メソッドを使用してください。
$user = new User(array('name' => 'John'));
$this->be($user);
データベースの内容を再構築したい場合は、seed
メソッドを使用します。
テストでデータベースを再シードする
$this->seed();
$this->seed('DatabaseSeeder');
シードの作成についてはドキュメントのマイグレーションとシードの章をご覧ください。
アプリケーションのリフレッシュ
ご存知の通り、Laravelのアプリケーション、つまりIoCコンテナへは、テストメソッドの中から$this->app
により、いつでもアクセスできます。このアプリケーションインスタンスは、それぞれのテストクラスごとにリフレッシュされます。特定のメソッドでアプリケーションを強制的に手動リフレッシュしたい場合は、refreshApplication
メソッドをテストメソッドで使用して下さい。これにより、テストケースが実行されることによりIoCコンテナに追加されたモックのような追加結合をリセットします。