アプリケーションテスト
イントロダクション
Laravelはアプリケーションに送るHTTPリクエストの作成、出力の検査、さらにフォームの入力もスラスラと書けるAPIを提供しています。例として、次に定義するテストを見てください。
<?php
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class ExampleTest extends TestCase
{
/**
* 基本的な機能テストの例
*
* @return void
*/
public function testBasicExample()
{
$this->visit('/')
->see('Laravel 5')
->dontSee('Rails');
}
}
visit
メソッドは、アプリケーションに対するGET
リクエストを作成します。see
メソッドは指定されたテキストが、アプリケーションから返されるレスポンスの中に存在することをアサートします。dontSee
メソッドは指定したテキストが、アプリケーションレスポンスの中へ返されていないことをアサートします。これはLaravelで使用できる最も基本的なアプリケーションテストです。
ルートに付けられた名前を使い、GET
リクエストを作るvisitRoute
メソッドも使用可能です。
$this->visitRoute('profile');
$this->visitRoute('profile', ['user' => 1]);
アプリケーションのテスト
もちろんシンプルに指定したレスポンスの中にテキストが現れるかアサートする以上のことが可能です。リンクのクリックとフォームの埋め込みを見てみましょう。
リンクのテスト
このテストではアプリケーションへのリクエストを作成し、帰ってきたレスポンス中のリンクを「クリック」、それから指定されたURIに到達することをアサートします。たとえば"About Us"のテキスト値を持つレスポンスの中のリンクがあると仮定しましょう。
<a href="/about-us">About Us</a>
では、このリンクをクリックし、正しいページに到達したことをアサートしましょう。
public function testBasicExample()
{
$this->visit('/')
->click('About Us')
->seePageIs('/about-us');
}
ユーザが正しい名前付きルートへ到達することを確認する、seeRouteIs
メソッドも使用できます。
->seeRouteIs('profile', ['user' => 1]);
フォームのテスト
Laravelはさらにフォームをテストするために多くのメソッドを提供しています。type
、select
、check
、attach
、press
メソッドはフォーム入力の全てを操作させてくれます。たとえば、アプリケーションの登録ページにこのフォームがあると考えてください。
<form action="/register" method="POST">
{{ csrf_field() }}
<div>
Name: <input type="text" name="name">
</div>
<div>
<input type="checkbox" value="yes" name="terms"> Accept Terms
</div>
<div>
<input type="submit" value="Register">
</div>
</form>
このフォームを完全に埋め、結果を確認するテストが書けます。
public function testNewUserRegistration()
{
$this->visit('/register')
->type('Taylor', 'name')
->check('terms')
->press('Register')
->seePageIs('/dashboard');
}
もちろん、フォームにラジオボタンやドロップボックスのような他の入力が含まれていても、同様にそうしたフィールドを簡単に埋めることができます。フォーム操作メソッドのリストを見てください。
メソッド | 説明 |
---|---|
$this->type($text, $elementName) |
指定したフィールドに「タイプ」します。 |
$this->select($value, $elementName) |
ラジオボタンかドロップダウンフィールドを「選択」します。 |
$this->check($elementName) |
チェックボックスフィールドを「チェック」します。 |
$this->uncheck($elementName) |
チェックボックスフィールドを「非チェック」にします。 |
$this->attach($pathToFile, $elementName) |
フォームにファイルを「添付」します。 |
$this->press($buttonTextOrElementName) |
指定したテキストか名前のボタンを「押し」ます。 |
ファイル入力
フォームにfile
入力タイプが含まれているならば、attach
メソッドを使いフォームにファイルを添付できます。
public function testPhotoCanBeUploaded()
{
$this->visit('/upload')
->attach($pathToFile, 'photo')
->press('Upload')
->see('Upload Successful!');
}
JSON APIのテスト
さらにLaravelは、JSON
APIとそれらのレスポンスをテストするために、多くのヘルパも用意しています。たとえば、json
、get
、post
、put
、patch
、delete
メソッドは各HTTP動詞でのリクエストを発行するために使用します。また簡単にデータとヘッダをメソッドに渡すこともできます。手始めに、/user
に対するPOST
リクエストを作成し、期待したデータが返ってくることをアサートするテストを書いてみましょう。
<?php
class ExampleTest extends TestCase
{
/**
* 基本的な機能テストの例
*
* @return void
*/
public function testBasicExample()
{
$this->json('POST', '/user', ['name' => 'Sally'])
->seeJson([
'created' => true,
]);
}
}
Tip!!
seeJson
メソッドは渡された配列をJSONに変換します。次にそのJSONが、JSONレスポンス全体のいずれかに現れるかを確認します。ですから、他のプロパティーがJSONレスポンスに含まれていたとしても、指定した部分が存在する限り、テストはパスします。
厳格な一致の確認
指定した配列がアプリケーションから返されるJSONと厳格に一致するかを確認したい場合は、seeJsonEquals
メソッドを使用してください。
<?php
class ExampleTest extends TestCase
{
/**
* 基本的な機能テストの例
*
* @return void
*/
public function testBasicExample()
{
$this->json('POST', '/user', ['name' => 'Sally'])
->seeJsonEquals([
'created' => true,
]);
}
}
構造の一致の確認
JSON形式が特定の構造にピタリと当てはまるかを確認することもできます。このシナリオでは、期待するJSON構造をseeJsonStructure
メソッドに渡してください。
<?php
class ExampleTest extends TestCase
{
/**
* 基本的な機能テストの例
*
* @return void
*/
public function testBasicExample()
{
$this->get('/user/1')
->seeJsonStructure([
'name',
'pet' => [
'name', 'age'
]
]);
}
}
上の例ではname
および、name
とage
を持つネストしたpet
オブジェクトを受け取ることを期待しています。seeJsonStructure
は、レスポンスが余計なキーを含んていても失敗しません。たとえば、pet
がweight
属性を持っていても、テストをパスします。
*
を使い、戻ってきたJSON構造がリストを持っていること、そして各リストが最低でも持っている属性を指定することもできます。
<?php
class ExampleTest extends TestCase
{
/**
* 基本的な機能テストの例
*
* @return void
*/
public function testBasicExample()
{
// リスト中の各ユーザが、最低でもid、name、email属性を持っていることをアサートする
$this->get('/users')
->seeJsonStructure([
'*' => [
'id', 'name', 'email'
]
]);
}
}
*
記述法はネストもできます。次の例の場合、JSONレスポンスの各ユーザは指定されている属性を持っており、各ユーザの各ペットも指定されている属性を持っていることを宣言します。
$this->get('/users')
->seeJsonStructure([
'*' => [
'id', 'name', 'email', 'pets' => [
'*' => [
'name', 'age'
]
]
]
]);
セッション/認証
Laravelはテスト時にセッションを操作するたくさんのヘルパも提供しています。1つ目は指定した配列をセッションに保存するwithSession
メソッドです。これはアプリケーションのリクエストをテストする前に、データをセッションにロードしたい場合に便利です。
<?php
class ExampleTest extends TestCase
{
public function testApplication()
{
$this->withSession(['foo' => 'bar'])
->visit('/');
}
}
もちろん認証済みのユーザのようなユーザ状態をセッションへ保持するのは一般的です。actingAs
ヘルパメソッドは現在認証済みのユーザを指定する簡単な手段を提供します。たとえば、モデルファクトリでユーザを生成し、認証してみましょう。
<?php
class ExampleTest extends TestCase
{
public function testApplication()
{
$user = factory(App\User::class)->create();
$this->actingAs($user)
->withSession(['foo' => 'bar'])
->visit('/')
->see('Hello, '.$user->name);
}
}
ユーザの認証にどのガードを使用するかを指定したい場合、actingAs
メソッドの第2引数にガード名を渡します。
$this->actingAs($user, 'api')
ミドルウェアの無効化
アプリケーションをテストするとき、いくつかのテストではミドルウェアを無効にするほうが便利だと気がつくでしょう。これによりミドルウェアに関わらずにルートやコントローラーのテストが可能になります。LaravelはシンプルなWithoutMiddleware
トレイトを用意しており、これを使えば自動的にテストクラスのミドルウェアを無効にできます。
<?php
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class ExampleTest extends TestCase
{
use WithoutMiddleware;
//
}
いくつかのテストメソッドだけでミドルウェアを無効にしたい場合は、withoutMiddleware
メソッドをテストメソッドの中で呼び出してください。
<?php
class ExampleTest extends TestCase
{
/**
* 基本的な機能テストの例
*
* @return void
*/
public function testBasicExample()
{
$this->withoutMiddleware();
$this->visit('/')
->see('Laravel 5');
}
}
カスタムHTTPリクエスト
アプリケーションに対してカスタムHTTPリクエストを作成し、完全なIlluminate\Http\Response
オブジェクトを取得したい場合は、call
メソッドを使ってください。
public function testApplication()
{
$response = $this->call('GET', '/');
$this->assertEquals(200, $response->status());
}
POST
やPUT
、PATCH
リクエストの場合、そのリクエストに入力データの配列を渡すことができます。もちろん、このデーターはRequestインスタンスを使用し、ルートやコントローラーで使用できます。
$response = $this->call('POST', '/user', ['name' => 'Taylor']);
PHPUnitアサート
PHPUnitテスト用に、数多くの追加アサートメソッドをLaravelは提供しています。
メソッド | 説明 |
---|---|
->assertResponseOk(); |
クライアントのレスポンスがOKのステータスコードを受け取ることを宣言 |
->assertResponseStatus($code); |
クライアントのレスポンスが指定したコードであることを宣言 |
->assertViewHas($key, $value = null); |
レスポンスのビューに指定したデータが含まれていることを宣言 |
->assertViewHasAll(array $bindings); |
ビューが指定したデータのリストを持っていることを宣言 |
->assertViewMissing($key); |
ビューが指定したデータを含んでいないことを宣言 |
->assertRedirectedTo($uri, $with = []); |
クライアントが指定したURIへリダイレクトすることを宣言 |
->assertRedirectedToRoute($name, $parameters = [], $with = []); |
クライアントが指定したルートへリダイレクトされることを宣言 |
->assertRedirectedToAction($name, $parameters = [], $with = []); |
クライアントが指定したアクションへリダイレクトすることを宣言 |
->assertSessionHas($key, $value = null); |
セッションが指定した値を持つことを宣言 |
->assertSessionHasAll(array $bindings); |
セッションが指定したリストを持つことを宣言 |
->assertSessionHasErrors($bindings = [], $format = null); |
セッションにエラー情報があることを宣言 |
->assertHasOldInput(); |
セッションが直前の入力を持つことを宣言 |
->assertSessionMissing($key); |
セッションが指定したキーを持っていないことを宣言 |