LaravelでPHPUnitを使って、CRUD処理のテストを実施する方法を解説します。今回は投稿の新規作成ページの表示と、保存のためのテストコードを書いていきます。
面倒なテストを自動化して、開発作業を効率化していきましょう♪
PHPUnitの基本的な使い方を知りたい場合は、まずは下記記事をご覧ください。
Webアプリの前提条件
今回テストを行うためのWebアプリは、次のものとします。
■UserモデルとPostモデルがあり、データベースにはusersテーブルとpostsテーブルがある。
■usersテーブルとpostsテーブルは、次のような形で1対多のリレーションが設定してある。
■Webアプリには、postsテーブルにデータを作成・保存・更新・削除するための処理が入っている(CRUD処理が搭載済みとします)。
■routes/web.phpファイルには、下記のようにルート設定が入っている。
【routes/web.php】
1 2 3 |
use App\Http\Controllers\PostController; Route::resource('post', PostController::class); |
事前準備:PHPUnitの新規テスト作成と設定
まずは、前準備としてテストファイルの作成と設定を行っておきます。
下記コマンドを実行して、テストファイルを作成します。
1 |
php artisan make:test Post/PostTest |
tests/Feature/Post/PostTest.phpファイルが出来ます。今後は、このファイルにテストを書きます。
tests/Feature/Postの中のテストファイルのみを実行するよう、プロジェクト直下のphpunit.xmlの設定を変更しておきます。
【phpunit.xml】
1 2 3 4 5 6 7 8 9 10 11 12 13 |
(省略) <testsuites> <testsuite name="Unit"> <!-- 無効にする --> <!-- <directory suffix="Test.php">./tests/Unit</directory> --> </testsuite> <testsuite name="Feature"> <!-- 無効にする --> <!-- <directory suffix="Test.php">./tests/Feature</directory> --> <!-- 追加する --> <directory suffix="Test.php">./tests/Feature/Post</directory> </testsuite> </testsuites> |
デフォルトでは、Featureの中にログイン等のテストが用意されています。どのテストを実行するかはお好みで変えてください。
また、下部のデータベース名の設定も変更しておきましょう。
たとえば、”aaa”という名前でしたら、下記のようにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<php> <env name="APP_ENV" value="testing"/> <env name="BCRYPT_ROUNDS" value="4"/> <env name="CACHE_DRIVER" value="array"/> <!-- <env name="DB_DATABASE" value="testing"/> --> <!-- プロジェクトのデータベース名を入れる --> <env name="DB_DATABASE" value="aaa"/> <env name="MAIL_MAILER" value="array"/> <env name="QUEUE_CONNECTION" value="sync"/> <env name="SESSION_DRIVER" value="array"/> <env name="TELESCOPE_ENABLED" value="false"/> </php> </phpunit> |
事前準備:ファクトリーの作成
もうひとつ、準備をしておきましょう。
テストを行う時には、factoryを使ってダミーデータを作成します。ユーザーのダミーデータを作るfactoryはあらかじめあるので、今回はこれを使っていきます。
ユーザー以外に、投稿のダミーデータを作るためのfactoryも必要となります。こちらを作っておきましょう。下記コマンドを実行して、PostFactoryを作成します。
1 |
php artisan make:factory PostFactory |
次に、database/factories/PostFactory.phpファイルを開き、下記のようにコードをいれておきます。
【PostFactory.php】
1 2 3 4 5 6 7 8 |
public function definition(): array { return [ 'title'=>fake()->text(20), 'body'=>fake()->text(50), 'user_id'=>\App\Models\User::factory(), ]; } |
なおコードは、データベースの構造によって異なります。今回はpostsテーブルにtitleとbodyとuser_idがあるという想定でコードをいれています。
データベースの構造によって、内容は変えてくださいね。
CRUD処理のテスト:新規投稿作成ページ表示
それではいよいよ、テスト用シナリオを入れていきます。まずは、新規投稿作成ページを表示するためのテストを作っていきましょう。
tests/Feature/Post/PostTest.phpを開き、下記のようにコードを加えます。
【tests/Feature/Post/PostTest.php】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<?php namespace Tests\Feature; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Foundation\Testing\WithFaker; use Tests\TestCase; // 追加 use App\Models\User; use App\Models\Post; class PostTest extends TestCase { // 投稿の新規作成ページ表示テスト public function test_can_create_post() { $user = User::factory()->create(); $response = $this->actingAs($user)->get('/post/create'); $response->assertStatus(200); } } |
コードの意味を解説します。
- factoryを使って新規ユーザーを作成します。
- $this->actingAs($user) によって、作成したユーザーを現在のユーザーとして認証しています。つまりこの後の動作は、作成したユーザーが行ったことにできます。
- その後に->get(‘/post/create’); と入れています。これによって、作成したユーザーが ‘/post/create’ページを開いたことにします。
- $response->assertStatus(200);は、HTTPステータスが200であるかどうかを確認するコードです。HTTPステータスが200であれば、リクエストが無事サーバーで受理された状態ということになります。
上記コードによってダミーのユーザーを1人作成して、この人に、投稿の新規作成ページにアクセスできるかテストしてもらっているわけです。
コードを保存したら、下記コマンドを実行します。
1 |
php artisan test |
ユーザーが無事にページを開ける場合には、下記のように返ってきます。
データベースを確認すると、ユーザーが1人登録されています。確認してみてください。
CRUD処理のテスト:新規投稿保存機能
続いて、CRUD処理のテスト2つ目、新規投稿保存のためのテストを作ってみましょう。
tests/Feature/PostTest.phpに下記のコードを追加します。
【tests/Feature/PostTest.php】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// 投稿の保存テスト public function test_can_store_post() { $user = User::factory()->create(); $response = $this->actingAs($user)->post('/post', [ 'title' => 'テスト投稿', 'body' => 'テスト投稿をします', ]); $response->assertStatus(302); $this->assertDatabaseHas('posts', [ 'title' => 'テスト投稿', 'body' => 'テスト投稿をします', 'user_id' => $user->id, ]); } |
コードの意味は下記のとおりです。
- factoryを使って新規ユーザーを作成します。
- $this->actingAs($user) によって、作成したユーザーを現在のユーザーとして認証しています。つまりこの後の動作は、作成したユーザーが行ったことにできます。
- その後の->post 以下のコードによって、このユーザーによる新規投稿を作成しています。
- $response->assertStatus(302);は、HTTPステータスが302であるかどうかを確認するコードです。HTTPステータスが302であれば、リクエストが指定したURLにリダイレクトされた状態ということになります。
- $this->assertDatabaseHasによって、指定した条件に一致するデータがデータベース中に存在するかを確認しています。
上記コードによってダミーのユーザーを1人作成して、この人に投稿を新規作成してもらいます。その後、無事データがデータベースに保存されているかをテストしています。
コードを保存したら、下記コマンドを実行します。
1 |
php artisan test |
無事にデータが保存された場合には、下記のように返ってきます。
データベースには、ユーザーと投稿のデータが1つずつ保存されているはずです。確認してくださいね。
データベースにテストデータが保存されるのを避ける方法
テストを行うと、そのたびにデータベースにテストデータが加わっていきます。
「テストのたびにデータが保存されるのを避けたい」という場合は、tests/Feature/PostTest.phpの上部に下記のコードを追加します。
【tests/Feature/PostTest.php】
1 2 3 4 |
class PostTest extends TestCase { // 追加 use RefreshDatabase; |
ただしコードを入れると、既存のデータも消えてしまいます。
ご利用には注意してくださいね。
さいごに
今回は、PHPUnitを使って、CRUD処理のうち、【新規作成ページ表示】と【投稿の新規保存】のテストを自動化するための方法を説明しました。
CRUD処理では、編集・更新・削除の処理も入ってきます。
次の記事では、これらの処理について、PHPUnitでどのようにテストを行うか解説していきます。
引き続きPHPUnitを実践的に使っていきましょう♪
なお「そもそもCRUD処理を作る方法について分からない」「Laravelの基本の使い方を学びたい」
と思ったら、学習サイト【Laravelの教科書】をご活用ください。
こちらは、Laravelの使い方を学びつつ、CRUD処理をどんどん使って、実際のフォーラムサイトを作成していく実践的な教材です。
【Laravelの教科書を通じて作成するWebアプリのサンプルページ】
基礎編は無料です♪気になったら、上記ボタンをクリックして案内ページを見てみてくださいね。