LaravelでHTTPリクエストをテストする方法(GET, POSTなど)
生徒
「Laravelで作ったページが正しく動いているか確認するにはどうすればいいですか?」
先生
「HTTPリクエストのテストを書けば、実際にブラウザを開かなくても自動でチェックできますよ。」
生徒
「HTTPリクエストって何ですか?GETとかPOSTって聞いたことがあるんですが...」
先生
「HTTPリクエストはウェブページにアクセスしたり、フォームを送信したりする通信のことです。それでは、テストの書き方を詳しく見ていきましょう!」
1. HTTPリクエストとは?
HTTPリクエストとは、ウェブブラウザがサーバーに対して送る要求のことです。例えるなら、レストランで店員さんに注文を伝えることに似ています。お客さん(ブラウザ)が店員さん(サーバー)に「このメニューをください」と伝えると、店員さんが料理を持ってきてくれますよね。これと同じように、ブラウザがサーバーに「このページを見せてください」や「このデータを保存してください」と要求するのがHTTPリクエストです。
HTTPリクエストには主に以下のような種類があります。
- GETリクエスト: ページを表示したり、データを取得するときに使います。ブラウザでURLを入力してページを開く操作がこれにあたります。
- POSTリクエスト: フォームからデータを送信するときに使います。ログインフォームや問い合わせフォームの送信がこれにあたります。
- PUTリクエスト: データを更新するときに使います。ユーザー情報の編集などで使われます。
- DELETEリクエスト: データを削除するときに使います。投稿を削除する機能などで使われます。
Laravelでは、これらのHTTPリクエストを簡単にテストできる便利なメソッドが用意されています。実際にブラウザを操作しなくても、コードだけで動作確認ができるため、開発効率が大幅に向上します。
2. GETリクエストのテスト方法
GETリクエストは最も基本的なHTTPリクエストで、ページの表示をテストするときに使います。例えば、トップページが正しく表示されるかをテストしてみましょう。
<?php
namespace Tests\Feature;
use Tests\TestCase;
class HomePageTest extends TestCase
{
public function test_トップページが表示される()
{
$response = $this->get('/');
$response->assertStatus(200);
}
}
このテストでは、$this->get('/')でトップページにアクセスしています。assertStatus(200)は、HTTPステータスコードが200(成功)であることを確認するメソッドです。HTTPステータスコードとは、サーバーがリクエストに対してどのような結果を返したかを示す3桁の数字です。200は「正常に処理されました」という意味で、404は「ページが見つかりません」という意味です。
商品一覧ページのように、特定のURLにアクセスするテストも書けます。
public function test_商品一覧ページが表示される()
{
$response = $this->get('/products');
$response->assertStatus(200);
$response->assertSee('商品一覧');
}
assertSeeメソッドは、レスポンス(サーバーからの返答)に指定した文字列が含まれているかを確認します。この例では、ページに「商品一覧」という文字が表示されているかをチェックしています。
3. POSTリクエストのテスト方法
POSTリクエストは、フォームからデータを送信するときに使用します。例えば、お問い合わせフォームの送信をテストする場合は以下のようになります。
<?php
namespace Tests\Feature;
use Tests\TestCase;
class ContactFormTest extends TestCase
{
public function test_お問い合わせフォームが送信できる()
{
$response = $this->post('/contact', [
'name' => '山田太郎',
'email' => 'yamada@example.com',
'message' => 'お問い合わせ内容です'
]);
$response->assertStatus(302);
$response->assertRedirect('/contact/complete');
}
}
$this->post()メソッドの第一引数にはURL、第二引数には送信するデータを配列で指定します。この例では、名前、メールアドレス、メッセージの3つのデータを送信しています。
assertStatus(302)は、リダイレクト(ページ転送)が発生したことを確認しています。302は「一時的な移動」を意味するステータスコードで、フォーム送信後に完了ページに転送される場合によく使われます。assertRedirectメソッドで、どのページに転送されたかも確認できます。
4. データベースへの保存をテストする
フォームから送信されたデータがデータベースに正しく保存されるかをテストすることも重要です。例えば、商品登録機能をテストする場合は以下のようになります。
<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
class ProductCreateTest extends TestCase
{
use RefreshDatabase;
public function test_商品が登録できる()
{
$response = $this->post('/products', [
'name' => 'ノートパソコン',
'price' => 80000,
'description' => '高性能なノートパソコンです'
]);
$this->assertDatabaseHas('products', [
'name' => 'ノートパソコン',
'price' => 80000
]);
$response->assertRedirect('/products');
}
}
RefreshDatabaseトレイトを使うと、テストが終わるたびに自動的にデータベースがリセットされます。トレイトとは、複数のクラスで共通して使える機能をまとめたものです。これにより、テスト同士が影響し合わず、いつも同じ状態からテストを始められます。
assertDatabaseHasメソッドは、指定したテーブルに指定したデータが存在するかを確認します。この例では、productsテーブルに商品名が「ノートパソコン」で価格が80000円のレコード(データの行)が保存されているかをチェックしています。
5. PUTリクエストとDELETEリクエストのテスト
データの更新にはPUTリクエスト、削除にはDELETEリクエストを使います。これらもLaravelでは簡単にテストできます。
まず、商品情報を更新するPUTリクエストのテストを見てみましょう。
public function test_商品情報が更新できる()
{
$product = Product::create([
'name' => 'ノートパソコン',
'price' => 80000
]);
$response = $this->put('/products/' . $product->id, [
'name' => 'ノートパソコン',
'price' => 75000
]);
$this->assertDatabaseHas('products', [
'id' => $product->id,
'price' => 75000
]);
}
このテストでは、まず商品を作成してから、その商品の価格を更新しています。$this->put()メソッドを使って更新データを送信し、データベースが正しく更新されたかを確認しています。
次に、商品を削除するDELETEリクエストのテストです。
public function test_商品が削除できる()
{
$product = Product::create([
'name' => 'ノートパソコン',
'price' => 80000
]);
$response = $this->delete('/products/' . $product->id);
$this->assertDatabaseMissing('products', [
'id' => $product->id
]);
}
assertDatabaseMissingメソッドは、指定したデータがデータベースに存在しないことを確認します。削除機能が正しく動作しているかをテストする際に使用します。
6. レスポンスの内容を詳しくテストする
HTTPリクエストのテストでは、ステータスコードだけでなく、レスポンスの内容も詳しく確認できます。例えば、JSONデータが返ってくるAPI(アプリケーション間でデータをやり取りする仕組み)をテストする場合は以下のようになります。
public function test_商品APIが正しいJSONを返す()
{
$product = Product::create([
'name' => 'ノートパソコン',
'price' => 80000
]);
$response = $this->get('/api/products/' . $product->id);
$response->assertStatus(200);
$response->assertJson([
'name' => 'ノートパソコン',
'price' => 80000
]);
}
assertJsonメソッドは、レスポンスが指定したJSON構造を含んでいるかを確認します。JSONとは、データを整理して保存・送信するための形式の一つで、JavaScriptオブジェクト記法と呼ばれます。APIの開発では頻繁に使用される形式です。
また、特定の文字列がレスポンスに含まれていないことを確認するassertDontSeeメソッドもあります。
public function test_削除された商品は表示されない()
{
$response = $this->get('/products');
$response->assertDontSee('削除された商品');
}
このように、様々なアサーションメソッドを組み合わせることで、細かい動作まで確認できます。
7. 認証が必要なページのテスト
ログインしていないとアクセスできないページをテストする場合、テスト用のユーザーを作成してログイン状態を再現する必要があります。LaravelではactingAsメソッドを使って簡単にログイン状態をシミュレートできます。
<?php
namespace Tests\Feature;
use Tests\TestCase;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
class DashboardTest extends TestCase
{
use RefreshDatabase;
public function test_ログインユーザーはダッシュボードにアクセスできる()
{
$user = User::factory()->create();
$response = $this->actingAs($user)->get('/dashboard');
$response->assertStatus(200);
$response->assertSee('ダッシュボード');
}
public function test_未ログインユーザーはログインページにリダイレクトされる()
{
$response = $this->get('/dashboard');
$response->assertRedirect('/login');
}
}
User::factory()->create()は、テスト用のダミーユーザーを自動的に作成するメソッドです。ファクトリーとは、テストデータを簡単に生成するための仕組みです。actingAs($user)を使うことで、そのユーザーとしてログインした状態でリクエストを送信できます。
未ログインの状態をテストする場合は、actingAsを使わずに直接リクエストを送信します。認証が必要なページにアクセスすると、通常はログインページにリダイレクトされることを確認できます。
8. CSRFトークンとテスト
通常、LaravelのフォームにはCSRFトークンというセキュリティトークンが必要です。CSRFとはクロスサイトリクエストフォージェリの略で、悪意のあるサイトから不正な操作をされるのを防ぐ仕組みです。しかし、テストでは自動的にこのトークンが処理されるため、開発者が特別に意識する必要はありません。
もしCSRF保護を無効にしてテストしたい場合は、テストクラスで以下のように設定できます。
protected function setUp(): void
{
parent::setUp();
$this->withoutMiddleware(\App\Http\Middleware\VerifyCsrfToken::class);
}
setUpメソッドは、各テストメソッドが実行される前に毎回呼ばれる特別なメソッドです。ここでCSRF検証を無効にすることで、すべてのテストでCSRFトークンを気にせずにリクエストを送信できます。ただし、通常のテストではLaravelが自動的に処理してくれるため、この設定は不要です。
9. HTTPリクエストテストでよく使うアサーションメソッド
LaravelのHTTPテストでは、様々なアサーションメソッドが用意されています。よく使うものを一覧で紹介します。
| メソッド名 | 説明 |
|---|---|
assertStatus(200) |
HTTPステータスコードが指定した値であることを確認 |
assertSee('文字列') |
レスポンスに指定した文字列が含まれていることを確認 |
assertDontSee('文字列') |
レスポンスに指定した文字列が含まれていないことを確認 |
assertRedirect('/path') |
指定したパスにリダイレクトされることを確認 |
assertJson([...]) |
JSONレスポンスが指定した構造を含むことを確認 |
assertViewIs('view.name') |
指定したビューファイルが使われていることを確認 |
これらのメソッドを組み合わせることで、ページの表示からデータの保存、削除まで、あらゆる動作を自動的にテストできます。一度テストを書いておけば、プログラムを修正したときに既存の機能が壊れていないかを瞬時に確認できるため、安心して開発を進められます。
HTTPリクエストのテストは、Laravelアプリケーション開発において非常に重要なスキルです。最初は難しく感じるかもしれませんが、実際に手を動かしてテストを書いていくうちに、自然と身についていきます。簡単なテストから始めて、徐々に複雑なテストにチャレンジしていきましょう。