Laravel ではテストが用意されています PHPUnit ベースでコマンド一つ、IDEのアクセス一つでテストを走らせられます。
テスト: テストの準備 6.x Laravel
また、その中には API や静的ページをテストするための HTTP リクエスト、レスポンスを再現するものもあります。
HTTPテスト 6.x Laravel
HTTP テストでは次の様なコードで HTTP 通信のテストコードを記述できます。
/** tests\TestCase を継承したテストケースクラス の内部のテストメソッド */
// リクエスト定義を引数として渡すとレスポンスが返ってきます
$response = $this->json(// json リクエストを投げます. より詳細なリクエスト構築ができる call メソッドもあります。
'POST', // HTTP メソッド名を指定
route('api.user.search'), // ルーティングを指定。Laravel 内なので名前ルーティングがおすすめ
[ // リクエストのボディ。この例では検索リクエスト
'search' => [
'freeWord' => 'hoge',
],
'page' => 1,
'perPage' => 15,
],
['Authorization' => "Bearer ${authToken}",] // ヘッダ部。例は Bearer トークン
);
// レスポンスにはそのまま assert をかけられます
$response
->assertStatus(200) // リクエストは成功したかステータスコードで確認
->assertJson([ // レスポンスの中身の JSON をドット記法でチェック。例では検索結果一つ目の要素の name が"hoge太郎"であることをチェック
'items.0.name' => 'hoge太郎',
]);
コード上では便利ですが、ブラウザテストをしたことがある人からすると(例えば HTTP テストを試す前の自分)ネットワークを介するなら実行速度が遅くて手元ではとても使えたものではない、と思われがちです。しかしこの HTTP テストは高速です。その実体は Controller のあるメソッドを対象にした統合テストであり、その環境は一つの PHP プロセスの中で完結しています。
この HTTP テストの通信再現処理は vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php に全て詰まっており、次のメソッドに集約されています。数々のリクエスト構築メソッドは次の call メソッドの引数を減らすだけのラッパーです。
// \Illuminate\Foundation\Testing\Concerns\MakesHttpRequests::call
/**
* Call the given URI and return the Response.
*
* @param string $method
* @param string $uri
* @param array $parameters
* @param array $cookies
* @param array $files
* @param array $server
* @param string|null $content
* @return \Illuminate\Foundation\Testing\TestResponse
*/
public function call($method, $uri, $parameters = [], $cookies = [], $files = [], $server = [], $content = null)
{
$kernel = $this->app->make(HttpKernel::class);
$files = array_merge($files, $this->extractFilesFromDataArray($parameters));
$symfonyRequest = SymfonyRequest::create(
$this->prepareUrlForRequest($uri), $method, $parameters,
$cookies, $files, array_replace($this->serverVariables, $server), $content
);
$response = $kernel->handle(
$request = Request::createFromBase($symfonyRequest)
);
if ($this->followRedirects) {
$response = $this->followRedirects($response);
}
$kernel->terminate($request, $response);
return $this->createTestResponse($response);
}
何をやっているか大雑把に言えば、渡された定義を元にリクエストオブジェクトを構築して、LaravelのHTTP処理のカーネルクラスにリクエストオブジェクトを渡して、返ってきたレスポンスオブジェクトをテスト内で扱いやすいように加工して返す、です。これは public/index.php の Laravel のエントリーポイントとほとんど同じです。index.php が MakeHttpRequests.php と異なるのは $_GET 等の素の PHP のグローバル定義済み変数からリクエストオブジェクトを構築する点、HTTP通信処理終了前にクライアントにレスポンス内容を出力する点、の二点ほどです。 MakeHttpRequests.php は Laravel の HTTP 通信処理をほぼ完ぺきに再現しており、実際のリクエストとほぼ等しい処理を行う再現しやすく高速なテストを作れます。