本文へ移動
株式会社織翔
← コラム一覧に戻る
DevOps7分で読める

GitHub ActionsでLaravelのテストを自動化する基本

Laravelプロジェクトでphp artisan testを自動実行するために、GitHub Actionsの役割、ワークフロー構成、導入時の確認観点を整理します。

#GitHub Actions#Laravel#CI/CD#テスト自動化

執筆・監修:

この記事の対象と前提

この記事では、Laravel 12/13、PHP 8.3、SQLiteを使う基本的なプロジェクトを対象に、Pull Requestでテストを実行するGitHub Actionsのひな型を示します。Laravel 13はPHP 8.3以上を必要とし、Laravel 12もPHP 8.3をサポートします。利用中のLaravelとPHPの組み合わせは、導入前にLaravel 13.xのリリースノートとプロジェクトの composer.json で確認してください。

ここに掲載するコードは、読者自身のLaravelリポジトリへ合わせて使うテンプレートです。このWebサイトのリポジトリはLaravelプロジェクトではないため、掲載workflowを実際のGitHub ActionsやLaravelアプリで実行した結果ではありません。

CIは「人が確認しなくてよい仕組み」ではなく、同じ条件の確認を変更ごとに繰り返すための仕組みです。

導入前に決める運用ルール

workflowを書く前に、次の項目を決めます。

  • どのブランチへのpushとPull Requestで実行するか
  • テスト失敗時に誰が原因を確認するか
  • SQLiteで確認できる範囲と、本番同等DBで追加確認する範囲
  • 外部API、メール、キューをフェイクまたはテスト環境へ切り替える方法
  • 合格したcheckをマージ条件にするか

GitHubのworkflow syntaxでは、workflowを .github/workflows 配下のYAMLファイルとして定義し、pushpull_request などのイベントを指定します。対象ブランチが main 以外なら、以下の例の branches を実際の既定ブランチ名へ変更してください。

コピーして使えるLaravelテストworkflow

Laravelリポジトリに .github/workflows/laravel-test.yml を作り、次を保存します。.env.examplecomposer.lockdatabasestoragebootstrap/cache が通常のLaravel構成で存在する前提です。

name: Laravel Test

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

permissions:
  contents: read

jobs:
  test:
    runs-on: ubuntu-latest
    timeout-minutes: 15
    env:
      APP_ENV: testing
      DB_CONNECTION: sqlite
      DB_DATABASE: ${{ github.workspace }}/database/database.sqlite

    steps:
      - name: Checkout repository
        uses: actions/checkout@v6

      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: "8.3"
          extensions: pdo_sqlite
          coverage: none

      - name: Install Composer dependencies
        run: composer install --no-interaction --prefer-dist --no-progress

      - name: Prepare Laravel application
        run: |
          cp .env.example .env
          mkdir -p database
          touch database/database.sqlite
          chmod -R ug+rw storage bootstrap/cache database
          php artisan key:generate

      - name: Run database migrations
        run: php artisan migrate --force

      - name: Run Laravel tests
        run: php artisan test

Laravel公式のSQLite設定は、SQLiteファイルを作成し、DB_CONNECTION=sqlite と絶対パスの DB_DATABASE を指定する形です。この例もjobの環境変数と database/database.sqlite の作成先を一致させています。.env.example 内に別のDB設定があっても、workflowで与えた環境変数がCI用の接続先になります。

プロジェクトが .env.testing を正本にしている場合や、config/database.php を独自化している場合は、その実装を優先してください。設定キャッシュをリポジトリへ含めているなど特殊な構成では、準備手順に php artisan config:clear が必要かも確認します。

各stepで確認していること

actions/checkout は対象commitをrunnerへ取得します。shivammathur/setup-php はPHP 8.3と pdo_sqlite を準備し、Composerを利用できる状態にします。その後、lockfileに従って依存関係をインストールし、LaravelのアプリケーションキーとSQLiteファイルを準備します。

最後に php artisan test が終了コード0で完了し、Actions画面で各ステップとテスト結果を確認できることを確かめます。テスト用DBの設定に本番の接続情報を混ぜないでください。Laravel公式のTestingも参照できます。

SQLiteで確認できる範囲を決める

SQLiteはサービスコンテナが不要で、基本的なFeature testを始めやすい一方、本番がMySQLやPostgreSQLなら差異があります。JSON型、全文検索、照合順序、DB固有関数、制約の挙動などを利用する処理は、SQLiteのcheckだけで本番互換と判断できません。

まずSQLiteで高速な基本checkを作り、DB固有機能に依存する重要な処理は本番と同じ種類・対応versionのDBを使う別jobで確認する、という分け方ができます。APIレスポンスのキー契約をFeature testで固定する例はLaravelのスネークケースとキャメルケースで紹介しています。

Actionの参照方法と更新方針

actions/checkout はGitHub公式Actionです。shivammathur/setup-php は第三者Actionなので、採用前と更新時にsetup-php公式リポジトリの所有者、README、Releases、参照するタグまたはcommitを確認します。

例では読みやすく更新を追いやすいmajor tagを使っています。タグは更新を取り込みやすい一方で可変です。GitHubのSecure use referenceでは、完全なcommit SHAへのpinを不変な参照として推奨しています。commit pinは意図しない参照先変更を抑えられますが、更新を自動では取り込まないため、release notesを確認してSHAを更新する運用が必要です。リポジトリや組織のセキュリティ方針に合わせて選びます。

テスト成功をマージ条件にする

workflowが実行されても、失敗したままマージできれば見落としは残ります。運用が固まったら、GitHubのbranch protectionまたはrulesetで test jobのstatus checkを必須にします。保護ブランチのrequired status checksでは、必要なcheckが合格するまで保護ブランチへマージできないように設定できます。

branch filterやpath filterでworkflow自体がskipされると、必須checkがPendingのままになる構成があります。workflowの発火条件とbranch protectionの必須check名をセットで確認してください。

外部APIの疎通確認が必要な場合

外部サービスはLaravelのfakeやmockで確認し、本物の疎通が必要な場合だけ、データと権限を管理した検証環境を使います。リクエストと期待結果の揃え方はPostmanの基本手順を参照してください。