バグの混入をなくし開発システムの信頼性(品質)を確保するためには,十分なテストが必要です.開発中に何度もテストを行いますが,手動によるテストではなく,テストコードを書いて自動的にテストができるようにすることが重要です.これにより確実に,かつ,短時間でテストがいつでも実行できるようになります.また,テストカバレッジ(テスト網羅度)を計測して,テスト漏れがないかを常に確認することも重要です.まずはカバレッジを計測するための php-xdebug がインストールされているかを確認します.ここの手順で ubuntu をインストールした場合にはすでにインストールできているはずです.
vagrant@ubuntu2204 comment_app $ sudo dpkg --list | grep php-xdebug ⏎
ii php-xdebug 3.1.2+2.9.8+2.8.1+2.5.5-4 amd64 Xdebug Module for PHP
vagrant@ubuntu2204 comment_app $
自動テストのテストコードは tests 以下のディレクトリに保存されます.Feature サブディレクトリには機能テスト,Unit サブディレクトリには単体テストのコードを設置します.まずはディレクトリの中身を覗いてみます.
vagrant@ubuntu2204 comment_app $ ls tests/ ⏎ CreatesApplication.php Feature TestCase.php Unit vagrant@ubuntu2204 comment_app $ ls tests/Feature/ ⏎ ExampleTest.php vagrant@ubuntu2204 comment_app $ ls tests/Unit/ ⏎ ExampleTest.php vagrant@ubuntu2204 comment_app $
新しいテストコードを生成するために,php artisan make:test テストコード名
を実行します.これによって,tests/Feature ディレクトリに新たな機能テストのひな形が生成されます.また,--unit
オプションをつけることにより,test/Unit ディレクトリに単体テストのひな形が生成されます.
vagrant@ubuntu2204 comment_app $ php artisan make:test CommentsControllerTest ⏎ INFO Test [tests/Feature/CommentsControllerTest.php] created successfully. vagrant@ubuntu2204 comment_app $ ls tests/Feature/ ⏎ CommentsControllerTest.php ExampleTest.php vagrant@ubuntu2204 comment_app $ php artisan make:test CommentsControllerTest --unit ⏎ INFO Test [tests/Unit/CommentsControllerTest.php] created successfully. vagrant@ubuntu2204 comment_app $ ls tests/Unit/ ⏎ CommentsControllerTest.php ExampleTest.php vagrant@ubuntu2204 comment_app $
最初から存在していた機能テスト ExampleTest.php にはトップページ / にアクセスして200番のステータスコードを受け取ることを確認するテストケースが記載されています.ここでは存在しないページ /hoge にアクセスして404エラーのステータスコードを受け取ることを確認するテストケースを追加してみます.
tests/Feature/ExampleTest.php
<?php
namespace Tests\Feature;
// use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class ExampleTest extends TestCase
{
/**
* A basic test example.
*/
public function test_the_application_returns_a_successful_response(): void
{
$response = $this->get('/');
$response->assertStatus(200);
}
public function test_the_application_returns_a_404_error_response(): void
{
$response = $this->get('/hoge');
$response->assertStatus(404);
}
}
実際に自動テストを実行するためには php artisan test
コマンドを用います.次のとおりテストコードのファイル名を指定すると,そのテストのみが実行されます.このテストでは2種類のテストを実行していずれもパスしています.
vagrant@ubuntu2204 comment_app $ php artisan test tests/Feature/ExampleTest.php ⏎
PASS Tests\Feature\ExampleTest
✓ the application returns a successful response 0.11s
✓ the application returns a 404 error response 0.03s
Tests: 2 passed (2 assertions)
Duration: 0.20s
vagrant@ubuntu2204 comment_app $
また,ファイル名を指定せずに php artisan test
コマンドを実行すると,すべてのテストコードが順に(おそらく単体テスト/機能テストがそれぞれアルファベット順に)実行されます.現時点では0.2秒程度で終了していますが,大規模なシステム開発の際には,すべてのテストケースを実行するためには相当の時間を要する可能性があります.そのような場合には,特定のテストコードのみを実行したり,CPU のマルチコアを使った並列テストも必要になるでしょう.
vagrant@ubuntu2204 comment_app $ php artisan test ⏎
PASS Tests\Unit\CommentsControllerTest
✓ example
PASS Tests\Unit\ExampleTest
✓ that true is true
PASS Tests\Feature\CommentsControllerTest
✓ example 0.10s
PASS Tests\Feature\ExampleTest
✓ the application returns a successful response 0.02s
✓ the application returns a 404 error response 0.02s
Tests: 5 passed (5 assertions)
Duration: 0.21s
vagrant@ubuntu2204 comment_app $
さらに CommentsControllerTest に幾つかのテストケースを書いてみます.
tests/Feature/CommentsControllerTest.php
<?php
namespace Tests\Feature;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;
class CommentsControllerTest extends TestCase
{
/**
* A basic feature test example.
*/
public function test_comments_index(): void
{
$response = $this->get('/comments');
$response->assertStatus(200);
}
public function test_comments_show_3(): void
{
$response = $this->get('/comments/3');
$response->assertStatus(200);
}
public function test_comments_edit_3(): void
{
$response = $this->get('/comments/3/edit');
$response->assertStatus(200);
}
}
実際にテストを実行してみると,すべてのテストをパスできたことが確認できました.
vagrant@ubuntu2204 comment_app $ php artisan test ⏎
PASS Tests\Unit\CommentsControllerTest
✓ example
PASS Tests\Unit\ExampleTest
✓ that true is true
PASS Tests\Feature\CommentsControllerTest
✓ comments index 0.13s
✓ comments show 3 0.02s
✓ comments edit 3 0.02s
PASS Tests\Feature\ExampleTest
✓ the application returns a successful response 0.03s
✓ the application returns a 404 error response 0.03s
Tests: 7 passed (7 assertions)
Duration: 0.30s
vagrant@ubuntu2204 comment_app $
自動テストの内容をコード化しておくことで,開発中に機能を追加・変更するたびに自動テストを簡単に実行することができるようになります.思わぬバグを作り込んでしまっても,自動テストによってバグを発見できる可能性が高くなります.しかし,ソースコードのどの部分がテストされて,どの部分のテストが実行できていないのかを知ることも重要です.次のページではテストカバレッジ(テスト網羅度)を計測します.