インプルの矢島です。
私は業務でLaravelを書きますが、テストコードの網羅率など気にする機会がありました。Laravel 9にはtestコマンドにオプションをつけることで網羅率を検出できる機能がリリースされたため、試してみることにしました。
環境
- Laravel 9
- Laravel Sail
- Xdebug 3.1.5
コード
クエリパラメータで送信されてきた食べ物が、好きな食べ物かどうか判断するコードを書きます。(適当なコードで申し訳ないです。。)
// .env
SAIL_XDEBUG_MODE=develop,debug,coverage
// FoodController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class FoodController extends Controller
{
public function favoriteFood(Request $request)
{
$food = $request->food ?? "トマト";
if ($food == "お寿司") {
return "私の好きな食べ物です";
} else {
return "私のまあまあ好きな食べ物です";
}
}
}
// web.php
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\FoodController;
Route::get('/', function () {
return view('welcome');
});
Route::get('favorite-food', [FoodController::class, 'favoriteFood']);
// tests/Feature/FoodTest.php
<?php
namespace Tests\Feature;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;
class FoodTest extends TestCase
{
public function test_example()
{
$query1 = [
"food" => "お寿司"
];
$response1 = $this->get(route('favorite_food', $query1));
$response1->assertSeeText("私の好きな食べ物です");
}
}
カバレッジを出力してみる
// ターミナル
php artisan test --coverage
// Sailの場合は ./vendor/bin/sail artisan test --coverage
FoodControllerのカバレッジが75%だということ、そして、17行目の項目を網羅する必要があることが読み取れます。
では、FoodControllerの17行目を網羅できるようにテストコードを以下のように修正します。
public function test_example()
{
$query1 = [
"food" => "お寿司"
];
$response1 = $this->get(route('favorite_food', $query1));
$response1->assertSeeText("私の好きな食べ物です");
$query2 = [
"food" => "トマト"
];
$response2 = $this->get(route('favorite_food', $query2));
$response2->assertSeeText("私のまあまあ好きな食べ物です");
}
テストを実行すると、網羅率が100%になりました。
最低ラインを設定する
// ターミナル
php artisan test --coverage --min=80.3
その他
- テストカバレッジは命令網羅(C0)のみ
- 特定のテストケースを実行時には —coverageを出力することができない
感想
個人的には、よく使われているPHPUnitとXdebugのカバレッジの方が見やすく感じます。また、命令網羅のみなのが、使いづらいですね。ただ、パッと情報を確認したいときはこちらのコマンドでも良いかもしれません。
他にもLaravel 9の新機能があるので、試していきたい思います〜