この記事のゴール
- LaravelでPHPUnitを使って自動テストを実行しオールグリーン(全てOK)にする。
前提条件
- Laravel でPHPUnitが使える状態。
※まだの場合は、以前の記事を参考にしてください。
- フォームから基本的なCRUD(作成/読取/更新/削除)操作ができる状態
※まだの場合は前回の記事を参考にしてください。
これからやる作業
- テスト用環境設定ファイル作成
- テスト用データベースのマイグレーション
- テストコード作成
- テスト実行
テスト用環境設定ファイル作成
テスト実行時には、テスト用のデータベースが用意されているので、
そちらを確実に使用するように、Laravelの環境ファイルを作成します。
プロジェクトトップフォルダにある「.env」ファイルをコピーして、
新しいファイル「.env.testing」を作成します。
![](https://macocci7.net/blog/wp-content/uploads/2023/05/phpunit04.png)
次のように編集して保存します。
修正す箇所は、2行目と14行目で、「=」の後ろを「testing」に修正するだけです。
APP_NAME=Laravel
APP_ENV=testing
APP_KEY=base64:r3t3Xyd9S12D2F19ZxkoFCCFN+0IAhei/2LRIJ1U5dc=
APP_DEBUG=true
APP_URL=http://localhost
LOG_CHANNEL=stack
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=debug
DB_CONNECTION=mysql
DB_HOST=mariadb
DB_PORT=3306
DB_DATABASE=testing
DB_USERNAME=sail
DB_PASSWORD=password
・・・(以下省略)・・・
テスト用データベースのマイグレーション
現在、テスト用データベースには、「todos」などの前回作成したテーブルがありません。
次のコマンドでシーダーまで含めて実行しましょう。
php artisan migrate:fresh --seed --env=testing
最後の「–env=testing」を忘れると「webapp」データベースの方が
マイグレーションされてしまうので、間違えないように注意します。
![](https://macocci7.net/blog/wp-content/uploads/2023/05/phpunit05-1-1024x355.png)
念のため、テスト用データベースのtodosテーブルにレコードがあるか確認します。
各自の好きな確認方法でかまいませんが、ここではMySQL CLIで確認していきます。
mysql -h mariadb -u sail -p
![](https://macocci7.net/blog/wp-content/uploads/2023/05/phpunit06.png)
show databases;
![](https://macocci7.net/blog/wp-content/uploads/2023/05/phpunit07.png)
use testing;
![](https://macocci7.net/blog/wp-content/uploads/2023/05/phpunit08.png)
show tables;
![](https://macocci7.net/blog/wp-content/uploads/2023/05/phpunit09.png)
select * from todos;
![](https://macocci7.net/blog/wp-content/uploads/2023/05/phpunit10.png)
シーダーによってレコードが登録されていることが確認できました。
テストコード作成
次のコマンドを実行します。
php artisan make:test TodoTest
![](https://macocci7.net/blog/wp-content/uploads/2023/05/phpunit01.png)
フォルダ [tests/Feature/] 内に、[TodoTest.php] が作成されます。
![](https://macocci7.net/blog/wp-content/uploads/2023/05/phpunit02.png)
このファイルを開いてみると、次のようなコードが書かれています。
<?php
namespace Tests\Feature;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;
class TodoTest extends TestCase
{
/**
* A basic feature test example.
*/
public function test_example(): void
{
$response = $this->get('/');
$response->assertStatus(200);
}
}
14行目~19行目が、テスト時に実行される処理です。
ページや機能ごとにテストメソッドを作成していきます。
テストメソッド名は「test_」で始めます。
その後ろはテスト内容がわかりやすい名前を付けます。
まずは、この状態でこのコードだけ自動テストを実行してみます。
php artisan test tests/Feature/TodoTest.php
![](https://macocci7.net/blog/wp-content/uploads/2023/05/phpunit03.png)
無事、テストが通りました。
実行している処理は2個だけです(16行目、17行目)。
1.URL「/」(トップページ)のHTTPレスポンスを取得する。
2.HTTPレスポンスのステータスコードが「200」であることを確認する。
→リダイレクトで「302」だとエラーになります。
では、実際にコードを追記していきましょう。
<?php
namespace Tests\Feature;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;
use App\Models\Todo;
class TodoTest extends TestCase
{
/**
* A basic feature test example.
*/
public function test_index_can_get_todo_list(): void
{
Todo::truncate();
$todos = Todo::factory()->count(5)->create();
$response = $this->get(route('todo.index'))
->assertSee('TODOリスト')
->assertSee('新規登録')
->assertOk();
foreach ($todos as $todo) {
$response->assertSee($todo->todo);
}
}
public function test_retrieve_can_be_rendered(): void
{
Todo::truncate();
$todos = Todo::factory()->count(5)->create();
foreach ($todos as $todo) {
$this->get(route('todo.detail', ['id' => $todo->id]))
->assertSee('TODO詳細')
->assertSee('[編集]')
->assertSee('[削除]')
->assertSee('todo一覧')
->assertSee('やること: ' . $todo->todo)
->assertSee('状態:' . (1 == $todo->done ? '完了' : ''))
->assertOk();
}
}
public function test_create_can_be_rendered(): void
{
$this->get(route('todo.create'))
->assertSee('TODO新規登録')
->assertSee('やること:')
->assertSee('登録')
->assertSee('取消')
->assertOk();
}
public function test_store_can_store(): void
{
$todo = Todo::factory()->definition();
$this->post(route('todo.store'), $todo)
->assertValid()
->assertRedirect(route('todo.index'));
$this->get(route('todo.index'))
->assertSee($todo['todo']);
}
public function test_edit_can_be_rendered(): void
{
Todo::truncate();
$todos = Todo::factory()->count(5)->create();
foreach ($todos as $todo) {
$this->get(route('todo.edit', ['id' => $todo->id]))
->assertSee('TODO編集')
->assertSee('取消')
->assertSee('やること:')
->assertSee($todo->todo)
->assertSee('状態:')
->assertSee('未完')
->assertSee('完了')
->assertSee('登録')
->assertOk();
}
}
public function test_update_can_update(): void
{
Todo::truncate();
$todos = Todo::factory()->count(5)->create(['done' => 0]);
$id = 2;
$todo = 'update:' . $todos[$id]->todo;
$this->patch(route('todo.update', ['id' => $id]), [
'todo' => $todo,
'done' => 1,
])
->assertValid()
->assertRedirect(route('todo.detail', ['id' => $id]));
$this->get(route('todo.index'))
->assertSee($todo);
}
public function test_destroy_can_destroy(): void
{
Todo::truncate();
$todos = Todo::factory()->count(5)->create();
$id = 2;
$this->delete(route('todo.destroy', ['id' => $id]))
->assertRedirect(route('todo.index'));
$todos = Todo::all();
foreach ($todos as $todo) {
$this->assertTrue($todo->id !== $id);
}
}
}
細かい説明は長くなるので、記事を分割しました。
アサーションと呼ばれる確認用のメソッドは、公式サイトで確認してください。
テスト実行
では、テストを実行してみましょう。
php artisan test tests/Feature/TodoTest.php
![](https://macocci7.net/blog/wp-content/uploads/2023/05/phpunit11-1024x230.png)
オールグリーンです。気持ちイイですね。
では、他のテストもまとめて実行しましょう。
php artisan test
![](https://macocci7.net/blog/wp-content/uploads/2023/05/phpunit12-1024x215.png)
![](https://macocci7.net/blog/wp-content/uploads/2023/05/phpunit13-1024x204.png)
オールグリーンです。これで気持ちよく眠れます。
エラーが出た際の処理は次回を予定しています。
お疲れさまでした。
コメント