「PHPのテスト、書く気にならない問題」を解決するフレームワーク
PHPでテストを書こうとPHPUnitを開いたら、クラス定義、メソッド名の命名規則、$this->assert...の長い記述…。1つのテストケースを書くだけで10行以上のボイラープレートが必要。「テストが大事なのは分かってるけど、書くのが面倒」という声は、PHP開発者の間で根強くあります。
その問題を解決するために生まれたのがPestです。PHPUnitの上に構築された薄いラッパーで、Jest(JavaScript)やRSpec(Ruby)のようなシンプルな記法でPHPのテストが書けます。Laravelでは公式にサポートされており、新規プロジェクトではPestがデフォルトの選択肢になりつつあります。
Pestとは? ― PHPUnitをラップした「書きやすい」テストフレームワーク
Pest(公式サイト)は、Nuno Maduro氏が開発したPHP向けテストフレームワークです。内部的にはPHPUnitが動いているので、PHPUnitの全機能とエコシステムがそのまま使えます。違うのは書き方だけ。
公式が掲げるコンセプトは「Less boilerplate, more intent(ボイラープレートを減らし、意図に集中する)」。クラス定義やメソッド宣言を省略し、「何をテストしたいか」だけを書く設計です。
PHPUnitとの違い ― 同じテストを比べてみる
百聞は一見にしかず。同じテストをPHPUnitとPestで書き比べてみましょう。
PHPUnit
// tests/Feature/PostTest.php(PHPUnit)
namespace Tests\Feature;
use Tests\TestCase;
use App\Models\User;
use App\Models\Post;
class PostTest extends TestCase
{
public function test_authenticated_user_can_create_post(): void
{
$user = User::factory()->create();
$response = $this->actingAs($user)->postJson('/api/posts', [
'title' => 'テスト記事',
'body' => 'テスト本文です',
]);
$response->assertStatus(201);
$this->assertDatabaseHas('posts', ['title' => 'テスト記事']);
}
public function test_unauthenticated_user_cannot_create_post(): void
{
$response = $this->postJson('/api/posts', [
'title' => 'テスト記事',
'body' => 'テスト本文です',
]);
$response->assertStatus(401);
}
}Pest
// tests/Feature/PostTest.php(Pest)
use App\Models\User;
it('認証済みユーザーが記事を作成できる', function () {
$user = User::factory()->create();
$this->actingAs($user)->postJson('/api/posts', [
'title' => 'テスト記事',
'body' => 'テスト本文です',
])->assertStatus(201);
$this->assertDatabaseHas('posts', ['title' => 'テスト記事']);
});
it('未認証ユーザーは記事を作成できない', function () {
$this->postJson('/api/posts', [
'title' => 'テスト記事',
'body' => 'テスト本文です',
])->assertStatus(401);
});クラス定義、namespace宣言、メソッド宣言が消え、テストの意図だけが残っています。it()の第一引数が日本語でテストの説明を書けるので、何をテストしているかが一目瞭然です。
セットアップ方法
Laravel(推奨)
Laravel 11以降では、laravel newでプロジェクトを作成する際にPestを選択できます。既存プロジェクトに後から入れる場合は以下の通り。
# Pestと Laravelプラグインをインストール
composer require pestphp/pest --dev
composer require pestphp/pest-plugin-laravel --dev
# Pestの初期設定(tests/Pest.phpが生成される)
./vendor/bin/pest --init
# テスト実行
./vendor/bin/pest素のPHP(Laravel以外)
composer require pestphp/pest --dev
./vendor/bin/pest --init
./vendor/bin/pestPHPUnitのphpunit.xmlがそのまま使えるので、既存の設定を変更する必要はありません。
基本的なテストの書き方
test() と it()
Pestにはtest()とit()の2つの書き方があります。どちらも同じ動作で、好みの問題です。
// test() 形式
test('税込計算が正しい', function () {
expect(calcTaxIncluded(1000))->toBe(1100);
});
// it() 形式(英語で読みやすい)
it('calculates tax included price correctly', function () {
expect(calcTaxIncluded(1000))->toBe(1100);
});expect()(Pestのアサーション)
PHPUnitの$this->assertEquals()の代わりに、expect()でチェーン記法のアサーションが書けます。
// PHPUnit式
$this->assertEquals('hello', $result);
$this->assertCount(3, $items);
$this->assertTrue($user->isAdmin());
// Pest式(expect)
expect($result)->toBe('hello');
expect($items)->toHaveCount(3);
expect($user->isAdmin())->toBeTrue();データセット(パラメータ化テスト)
複数のパターンをまとめてテストしたい時に便利な機能です。
it('バリデーションが正しく動作する', function (string $field, mixed $value) {
$this->postJson('/api/posts', [$field => $value])
->assertUnprocessable()
->assertJsonValidationErrors($field);
})->with([
'タイトルが空' => ['title', ''],
'タイトルが長すぎ' => ['title', str_repeat('a', 256)],
'本文が空' => ['body', ''],
]);PHPUnitの@dataProviderと同じことが、->with()のチェーンだけで書けます。
PHPUnitから移行すべき? 判断基準
| 状況 | おすすめ |
|---|---|
| Laravelの新規プロジェクト | ✅ Pest(公式サポートあり、デフォルト推奨) |
| 既存のPHPUnitテストが大量にある | △ 段階的に移行(新しいテストだけPestで書く) |
| Laravel以外のPHPプロジェクト | ○ Pestは使えるが、プラグインの恩恵は少ない |
| チームにPHPUnitの知見しかない | △ 学習コストは低いが、チーム合意を取ってから |
PestはPHPUnitの上で動くので、同じプロジェクト内にPHPUnitのテストとPestのテストが共存できます。「全部書き換える」必要はなく、新しく書くテストからPestにすれば無理なく移行できます。
PHPテストの理解を深める関連記事
- Claude Codeとは?AI搭載のコーディングアシスタントを徹底解説 – テストケースの洗い出しやPestのコード生成をAIに任せる活用法
- GitHub Copilot日本語サイトが正式オープン!Free/Pro/Pro+全プラン徹底比較【2025年】 – Pestテストコードの補完にCopilotを活用する選択肢
- リリース前に必ず確認!バイブコーディング&非エンジニア向けWebアプリ安全チェックリスト – テストに加えてリリース前に確認すべきセキュリティチェック
- コマンドラインの基本と活用方法【初心者エンジニア向け】 – Composerやartisanコマンドの実行に必要なCLI操作の基本
- 「それ、上げちゃダメ!」GitHub管理で絶対守るべきセキュリティルールと対処法 – CI/CDでテストを自動実行する際のセキュリティ基本
まとめ:Pestは「PHPのテストを書く気にさせてくれる」フレームワーク
- Pestとは、PHPUnitの上に構築された、シンプルな記法でテストが書けるPHPテストフレームワーク
- クラス定義・メソッド宣言が不要。
it()とexpect()でテストの意図だけを書く - PHPUnitと完全互換。同じプロジェクト内で共存でき、段階的に移行可能
- Laravelでは公式サポート。新規プロジェクトならPestが第一選択肢
- データセット機能で、パラメータ化テストも
->with()のチェーンで書ける
テストを書かない理由が「面倒だから」なら、Pestを試してみてください。書く量が半分以下になるだけで、テストに対する心理的ハードルが驚くほど下がります。まずは1ファイル、1テストケースから。it('動く', function () { expect(true)->toBeTrue(); }); ― これが最初の一歩です。
