php elephant sticker
Photo by RealToughCandy.com on Pexels.com

【中級者向け】テスト駆動開発(TDD)で作る Laravel アプリ完全ガイド

この記事で学べること

  • PHPUnit を使ったモデル・コントローラ単体テストの基本
  • Laravel Dusk によるエンドツーエンドテストの構築手順
  • Pa11y を用いたアクセシビリティ自動テスト導入例
  • CI/CD パイプラインへのテスト自動化フロー
  • 実践的なサンプルコードとプロジェクト構成

想定読者

  • 単体テストや E2E テストをまだ体系的に学んでいない中級者エンジニア
  • プロジェクトの品質向上のために TDD を導入したい開発リーダー
  • アクセシビリティテストも自動化し、誰もが使いやすいサービスを目指す方

アクセシビリティレベル:★★★☆☆

PHPUnit/Dusk テストでは focusable 要素の存在確認、Pa11y でコントラスト比やラベルの有無をチェック


1. はじめに:なぜ TDD が Laravel で効果的なのか

テスト駆動開発(TDD)は「テストを書く → コードを書く → リファクタリング」のサイクルを高速に回すことで、
バグを早期に発見・修正し、保守性の高いコードベースを維持できる手法です。
Laravel はテスト機能がフレームワークに組み込まれており、
PHPUnit や Dusk を使ったテストがとても書きやすい設計になっています♡

  • 品質保証:リグレッションを防ぎながら機能追加できる
  • ドキュメント化:テスト自身がコードの利用例となる
  • 安心感:CI/CD で自動テストを回せば、マージ前に問題を検知

この記事では、TDD の流れに沿って PHPUnit → Dusk → Pa11y → CI までを一気通貫で学びましょう。


2. 環境準備:PHPUnit と Laravel Dusk のインストール

まずはプロジェクトにテスト環境を整えます。Laravel プロジェクト直下で以下を実行してください。

# PHPUnit はデフォルトでインストール済み
php artisan test --parallel

# Dusk のインストール
composer require --dev laravel/dusk
php artisan dusk:install
  • php artisan test で PHPUnit テストが実行可能に。
  • php artisan dusk でブラウザ自動操作テストが走るように設定完了。

また、Pa11y を使うために Node.js 環境を用意し、プロジェクトルートで以下を実行します。

npm install --save-dev pa11y

これでアクセシビリティ自動テストも書ける準備が整いました♪


3. 単体テスト入門:モデルとコントローラの PHPUnit テスト

3.1 モデルテストの例

たとえば、Post モデルの公開スコープをテストします。

// tests/Unit/PostTest.php
namespace Tests\Unit;

use Tests\TestCase;
use App\Models\Post;
use Illuminate\Foundation\Testing\RefreshDatabase;

class PostTest extends TestCase
{
    use RefreshDatabase;

    /** @test */
    public function it_only_returns_published_posts()
    {
        Post::factory()->count(3)->create(['published' => true]);
        Post::factory()->count(2)->create(['published' => false]);

        $published = Post::published()->get();

        $this->assertCount(3, $published);
    }
}
  • RefreshDatabase でテストごとにマイグレーションをリセット
  • /** @test */ アノテーションでメソッド名がテストとして認識される

3.2 コントローラテストの例

PostControllerstore メソッドをテストします。

// tests/Feature/PostControllerTest.php
namespace Tests\Feature;

use Tests\TestCase;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;

class PostControllerTest extends TestCase
{
    use RefreshDatabase;

    /** @test */
    public function guests_cannot_create_posts()
    {
        $response = $this->postJson('/api/posts', [
            'title' => 'Test',
            'body'  => 'Content',
        ]);

        $response->assertStatus(401);
    }

    /** @test */
    public function authenticated_users_can_create_posts()
    {
        $user = User::factory()->create();
        $this->actingAs($user, 'sanctum');

        $response = $this->postJson('/api/posts', [
            'title' => 'Hello',
            'body'  => 'World',
        ]);

        $response->assertStatus(201)
                 ->assertJson(['title' => 'Hello']);
    }
}
  • API リクエストには postJson を使い、ステータスコードと JSON 構造を検証

4. E2E テスト:Laravel Dusk で UI 操作を自動化

ブラウザ操作を伴うテストは Dusk が得意です。Dusk テストのサンプルを見てみましょう。

// tests/Browser/LoginTest.php
namespace Tests\Browser;

use Laravel\Dusk\Browser;
use Tests\DuskTestCase;
use App\Models\User;

class LoginTest extends DuskTestCase
{
    /** @test */
    public function user_can_login_via_login_page()
    {
        $user = User::factory()->create(['password' => bcrypt('secret')]);

        $this->browse(function (Browser $browser) use ($user) {
            $browser->visit('/login')
                    ->type('email', $user->email)
                    ->type('password', 'secret')
                    ->press('ログイン')
                    ->assertPathIs('/dashboard')
                    ->assertSee('ようこそ');
        });
    }
}
  • フォーム入力・ボタン押下・ページ遷移をシミュレート
  • assertSee でアクセシビリティ対応テキストの存在も確認

5. 自動アクセシビリティテスト:Pa11y の導入と活用

Pa11y を使い、ビルド後の静的 HTML をチェックします。

// package.json の scripts 部分
"scripts": {
  "test:a11y": "pa11y http://localhost:8000 --reporter html > a11y-report.html"
}
npm run test:a11y
  • コントラスト比、ラベルの有無、ARIA 属性の適切さを自動検証
  • 結果は a11y-report.html に出力され、CI 結合もカンタン

6. CI/CD への組み込みと運用フロー

GitHub Actions を例に、テスト自動化を組み込みます。

# .github/workflows/ci.yml
name: CI

on: [push, pull_request]

jobs:
  tests:
    runs-on: ubuntu-latest
    services:
      mysql:
        image: mysql:8
        env:
          MYSQL_ROOT_PASSWORD: password
        ports:
          - 3306:3306
    steps:
      - uses: actions/checkout@v2
      - uses: shivammathur/setup-php@v2
        with:
          php-version: 8.1
      - run: composer install --prefer-dist
      - run: cp .env.example .env
      - run: php artisan key:generate
      - run: php artisan migrate --force
      - run: php artisan test
      - run: npm install
      - run: npm run test:a11y
  • コードマージ前に全テストがパスしないと自動的に止まる安心フロー

7. まとめ:TDD で高品質&アクセシブルな Laravel 開発を

  1. PHPUnit でモデル・コントローラを単体テスト
  2. Laravel Dusk で UI を含む E2E テストを自動化
  3. Pa11y でアクセシビリティチェックを CI に組み込み
  4. GitHub Actions 等で CI/CD にテストを統合

TDD を取り入れれば、バグのない高品質なコードと、
誰もがアクセスしやすい Web サービスを両立できます♡
ぜひこのガイドを参考に、あなたのプロジェクトにも TDD を導入してみてくださいね!

投稿者 greeden

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)