テストについて
一般的なテストの入門方法については、実践!ユニットテスト入門 が参考になります。
YouTube もあります。
このページでは、テストについて、簡単にまとめます。
テストとは
プログラムを書いたとき、その動作が期待どおりかを確認することを「テスト」と呼びます。
この確認を、自動で効率よく行うためのツールとして、PHPUnit や Pest といったテストフレームワークがあります。
Laravel はテストを始めやすい
Laravel では、最初から PHPUnit や Pest が使えます。
基本的な手順は、次の通りです:
- artisan コマンドでテストのひな型ファイルを作成する
- テストファイルを編集する
- テストを実行する
Feature テストファイルの作成
まずは、 Laravel の機能を使う Feature テストの作り方を覚えましょう。
(慣れてきたら、ヘルプなどを使って Unit テストの方法も調べてください)
php artisan make:test コマンドで、テストのひな型を作ってくれます。
テストディレクトリは、Laravel と同じ階層構造にしておくと、便利です。
# app/Http/Controllers/PostController.php の Feature テストを書きたい
php artisan make:test Http/Controllers/PostControllerTest
# => tests/Feature/Http/Controllers/PostControllerTest.php が作成される
テストには、命名規約(名前を付けるときのルール)があります。
- テスト名は、大文字で始めてください
- テスト名の最後に
Testを付けてください
上記のように、 PostControllerTest だったり、 UserTest だったり、 HelloTest だったりします。
Feature テストファイルの編集
上記のコマンドで作成されたひな型のファイルは、 Laravel のバージョンによって、多少違うかもしれませんが、おおよそ以下のようになっているはずです。
tests/Feature/ExampleTest.php:
<?php
namespace Tests\Feature;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class ExampleTest extends TestCase
{
public function test_example(): void
{
$response = $this->get('/');
$response->assertStatus(200);
}
}
- class名(
ExampleTest)は、ファイル名に一致します - テストを実行するメソッド名は、
test_で初めます- PHPUnit の命名規約です
- ただし、最近は
#[Test]アトリビュートを使う方法もあり、今後アトリビュートが主流になってくると、メソッドの命名規則は無くなるかもしれません
- テストを実行しないメソッド(他のテストから利用するメソッド)は、
test_...とせず、#[Test]アトリビュートも付けません - テスト class は、
Tests\TestCaseを extends します Tests\TestCase->assertXxxx()というアサーションメソッドがたくさんありますTests\TestCase->get('/routing')でhttps://example.com/routingにアクセスしたときのレスポンスに相当するTestResponseオブジェクトが得られますTestResponseオブジェクトから、さまざまなアサーションメソッドが使えます
アサーションについては、 アサーションの調べ方 も合わせて読んでみてください。
データベースをセットアップすることも可能です。
その場合は、 class の中で、 use RefreshDatabase; を利用します。
class ExampleTest extends TestCase
{
use RefreshDatabase;
public function test...
}
初期データのシーダー( database/seeders/DatabaseSeeder.php )を実行することも可能です。
class ExampleTest extends TestCase
{
use RefreshDatabase;
public function test_example(): void
{
$this->seed();
...
}
}
テストを実行する
以下のコマンドで、 tests/ ファイル内のすべてのテストファイルを、全自動で実行することが可能です。
php artisan test
また、特定のディレクトリ内のテストファイルすべてを実行したり、特定のファイルだけを実行することも可能です。
php artisan test ./tests/Feature/
php artisan test ./tests/Feature/HelloTest.php
レッド・グリーン・リファクタリングとは
当サイトで表示される Red, Green,Refactor とは、本来テスト駆動開発(TDD)で使われる用語です。
簡単にいうと、以下の通りです:
- Red: テストを作成・実行し、失敗を確認する
- Green: 多少強引にでも、成功させる
- Refactor: 読みやすく書き換えたり、重複処理を整理したりする
Green の表示
まずは、成功(Green)するとどうなるか、確認しておきましょう。
テストを作ります。
bash:
php artisan make:test TrueIsTrueTest
テストを編集します。
tests/Feature/TrueIsTrueTest.php:
<?php
namespace Tests\Feature;
use Tests\TestCase;
class TrueIsTrueTest extends TestCase
{
public function test_必ず成功するテスト(): void
{
$this->assertTrue(true);
}
}
上記は、true が、 true であるかどうかテストしています。
テストを実行します。
bash:
php artisan test tests/Feature/TrueIsTrueTest.php
多少、バージョンによっても変わるかもしれませんが、わたしの環境では、以下のようになりました。
PASS のところが緑色になっていました。
PASS Tests\Feature\TrueIsTrueTest
✓ 必ず成功するテスト 0.42s
Tests: 1 passed (1 assertions)
Duration: 0.71s
Red の表示
今度は、あえて失敗するテストを書いてみます。
(あえて失敗するテストは、これから、たくさん書くことになります。)
bash:
php artisan make:test FalseIsNotTrueTest
テストファイルを編集します。
tests/Feature/FalseIsNotTrueTest.php:
<?php
namespace Tests\Feature;
use Tests\TestCase;
class FalseIsNotTrueTest extends TestCase
{
public function test_必ず失敗するテスト(): void
{
$this->assertTrue(false);
}
}
テストを実行します。
bash:
php artisan test tests/Feature/FalseIsNotTrueTest.php
これもバージョンによって多少変わるかもしれませんが、私の環境では、 FAILED のところが赤く表示され、きちんと失敗したことがわかります。
FAIL Tests\Feature\FalseIsNotTrueTest
⨯ 必ず失敗するテスト 0.41s
────────────────────────────────────────────────────────────────────────────
FAILED Tests\Feature\FalseIsNotTrueTest > 必ず失敗するテスト
Failed asserting that false is true.
at tests/Feature/FalseIsNotTrueTest.php:11
7▕ class FalseIsNotTrueTest extends TestCase
8▕ {
9▕ public function test_必ず失敗するテスト(): void
10▕ {
➜ 11▕ $this->assertTrue(false);
12▕ }
13▕ }
14▕
1 tests/Feature/FalseIsNotTrueTest.php:11
Tests: 1 failed (1 assertions)
Duration: 0.66s
エラー文は、最初のうちはビビるかもしれませんが、必要以上に怖がらないでください。
むしろ、失敗するつもりのテストで、エラーが表示されない方が、困ります。
当サイトでは、テストを利用して、 Laravel に入門します。
テスト駆動で入門することの意図については、 テスト駆動入門 を参照してください。