こんにちは、かつコーチです。
前回の記事でGitHub Actionsの基本的な仕組みを解説しましたが、「結局どう書けばテストが自動化できるの?」という疑問が残っている方も多いはずです。
この記事では、実際に手を動かしながら、Pull Request作成時にテストが自動実行されるワークフローを1つ作ってみます。
テスト自動化ワークフローとは?
決まった手順を代わりにこなしてくれる係員
テストの自動化とは、「依存パッケージを入れる」「テストコマンドを実行する」「結果を報告する」という一連の決まった手順を、人ではなくGitHub Actionsに代行させることです。
たとえるなら、毎回同じ検品作業をこなしてくれる係員を1人雇うようなものだとイメージしてください。
人間の係員は疲れていると見落としをすることもありますが、自動化された係員は寝ずに、手順書通り正確に同じチェックを繰り返してくれます。
なぜテストを自動化するのか
手元でテストを実行し忘れたままPull Requestを出してしまい、後からバグに気づいて焦った経験がある方もいるでしょう。
テストの自動化を設定しておけば、Pull Requestを出した瞬間に係員が検品を始めてくれるため、「テストを回し忘れた」という人為的なミスがそもそも起こりません。
さらに、テスト結果がPull Request画面に✅か❌で表示されるので、レビュアーもひと目で品質を確認できます。
実装手順:テスト自動化ワークフローを書く
今回はNode.jsプロジェクトを例に、Jestでのテストを自動化する例で進めます。
手順1:ワークフローファイルを作成する
$ mkdir -p .github/workflows
$ touch .github/workflows/test.yml
手順2:トリガーと実行環境を定義する
name: Run Tests
on:
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
Pull Requestがmainに向けて作成・更新されるたびに、係員が呼び出される設定です。
手順3:テストを実行するstepsを書く
steps:
- name: リポジトリを取得
uses: actions/checkout@v4
- name: Node.jsをセットアップ
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
- name: 依存パッケージをインストール
run: npm ci
- name: テストを実行
run: npm test -- --coverage
cache: "npm"を指定しておくと、依存パッケージのキャッシュが効き、2回目以降の実行が速くなります。
npm ciはnpm installと違い、package-lock.jsonの内容と完全に一致した状態で厳密にインストールするため、CI環境では基本的にこちらを使います。
手順4:複数バージョンでテストするマトリクス実行
複数のNode.jsバージョンで動作確認したい場合は、strategy.matrixを使うと1つの設定で並列実行できます。
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: ["18", "20", "22"]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
- run: npm test
これは、1人の係員に3種類のバージョン違いの検品を同時並行でこなしてもらっているイメージです。
つまずきやすい設定・注意点
npm ciを使う場合、リポジトリにpackage-lock.jsonがコミットされていないとエラーになります。
.gitignoreで誤ってlockファイルを除外していないか、事前に確認しておきましょう。
よくあるつまずきポイント・エラー対処
package-lock.jsonがなくてCIだけ失敗した話
私が実際に体験したのが、ローカルではnpm testが通るのに、CI上だけ失敗するというトラブルでした。
❌ Before:package-lock.jsonをgitignoreしていた
$ npm ci
npm ERR! The `npm ci` command can only install with an existing package-lock.json
ローカルではnpm installで動いていたため気づかず、CIのログを見て初めてpackage-lock.jsonがリポジトリに含まれていないことが分かりました。
係員に手順書(lockファイル)を渡し忘れていたので、検品のしようがなかったというわけです。
✅ After:package-lock.jsonをコミットし、.gitignoreから除外する
$ git add package-lock.json
$ git commit -m "add package-lock.json for CI"
以降、Node.jsプロジェクトを新規に作るときは、最初のコミットでpackage-lock.jsonが含まれているかを必ず確認するようにしています。
応用・一歩先の使い方
テストが失敗したらマージをブロックする
このワークフローのjob名(ここではtest)を、前回・前々回の記事で解説したProtected Branchのrequired_status_checksに指定すれば、テストが通らない限りPull Requestをマージできない状態にできます。
自動化した係員の検品結果が「不合格」なら、そもそも次の工程に進めない仕組みにするわけです。
カバレッジレポートをPull Requestに表示する
--coverageオプションで出力したカバレッジ結果を、codecovなどの外部アクションと連携させると、Pull Request画面にカバレッジの増減を自動コメントさせることもできます。
チームでカバレッジ基準を意識する文化を作りたい場合に役立ちます。
まとめ
この記事のポイント
- テスト自動化とは、決まった検品手順を代わりにこなしてくれる係員をワークフローとして配置すること
on.pull_requestでトリガーを設定し、stepsでセットアップからテスト実行までを記述するstrategy.matrixで複数バージョンのテストを並列実行できるpackage-lock.jsonをコミットし忘れるとnpm ciがCI上だけ失敗する
次に読むべき記事
テストの自動化ができたら、次は「GitHub Actionsでデプロイを自動化する基本」で、本番環境への反映まで自動化する方法に進んでみましょう。