CIとは何か
コードを書いていると、「テストを実行し忘れた」「ローカルでは動いたのに本番で動かない」といった経験はありませんか?
CI(継続的インテグレーション:Continuous Integration)は、こうした問題を防ぐための仕組みです。
継続的インテグレーションの基本
CIとは、コードの変更を頻繁に統合(マージ)し、その都度自動でテストやビルドを実行する開発手法です。
主な特徴は以下の通りです。
- 自動化:コミットやプルリクエストをトリガーにテストが自動実行される
- 早期発見:問題を早い段階で検出できる
- 品質保証:常にテストが通る状態を維持する
開発者がコードをプッシュするだけで、バックグラウンドでテストが走る。これがCIの魅力です。
なぜ自動テストが重要か
手動でテストを実行する場合、以下のような問題が起こりがちです。
- 実行忘れ:急いでいると、つい忘れてしまう
- 環境差異:「僕の環境では動くんだけど…」が発生する
- 時間のロス:チーム全員が毎回手動実行するのは非効率
自動化することで、これらの問題を解決できます。
|
|
自動化すれば、コードをプッシュするだけで、この作業が自動的に行われます。
GitHub Actionsの役割
GitHub Actionsは、GitHubが提供するCI/CDサービスです。
主な利点は以下の通りです。
- GitHubに統合:リポジトリと同じ場所で管理できる
- 無料枠が充実:パブリックリポジトリなら無料、プライベートでも月2,000分まで無料
- 豊富なエコシステム:様々な言語やツールに対応
- YAMLで設定:分かりやすい設定ファイル
次のセクションから、実際にGitHub Actionsを設定していきましょう。
GitHub Actionsの基本
GitHub Actionsは、ワークフローという単位で動作を定義します。
ワークフローファイルの配置
ワークフローは、リポジトリの特定の場所に配置します。
|
|
この.github/workflows/ディレクトリに、YAML形式の設定ファイルを置くだけで、GitHub Actionsが認識してくれます。
トリガーの設定(push, pull_request)
ワークフローは、様々なイベントで起動できます。よく使うのは以下の2つです。
|
|
この設定では、以下のタイミングでワークフローが実行されます。
mainまたはdevelopブランチへのプッシュmainブランチへのプルリクエスト
ジョブとステップの概念
ワークフローは、ジョブ(Job)とステップ(Step)で構成されます。
|
|
- ジョブ:独立した作業単位(例:テスト、ビルド、デプロイ)
- ステップ:ジョブ内の個別の処理(例:コードのチェックアウト、テスト実行)
複数のジョブを定義すると、並列実行されます。
Dockerを使ったテスト実行
前回までの連載で、Dockerを使ったローカル環境を構築しました。CI環境でも、同じDockerイメージを使えば、環境の一貫性が保たれます。
マトリックス戦略(複数のPerlバージョン)
GitHub Actionsのマトリックス戦略を使うと、複数のバージョンで同時にテストできます。
|
|
この設定により、Perl 5.36、5.38、5.40の3つのバージョンで並列にテストが実行されます。
cpanmで依存関係をインストール
PerlのモジュールをCI環境でインストールするには、cpanm(cpanminus)を使うのが一般的です。
|
|
--notestオプションで、依存モジュール自体のテストはスキップし、インストールだけを高速に行います。
--installdeps .で、カレントディレクトリのcpanfileやMakefile.PLから依存関係を読み取ってインストールします。
prove コマンドでテスト実行
テストの実行には、これまでと同じproveコマンドを使います。
|
|
オプションの意味:
-l:lib/ディレクトリをライブラリパスに追加-v:詳細な出力(verbose)
この1行で、t/ディレクトリ内のすべてのテストが実行されます。
実践:ワークフローの作成
それでは、実際にワークフローファイルを作成してみましょう。
.github/workflows/test.ymlの作成
以下の内容で.github/workflows/test.ymlを作成します。
|
|
このワークフローの流れを見ていきましょう。
- Checkout code:リポジトリのコードを取得
- Set up Perl:マトリックスで指定したPerlバージョンをセットアップ
- Install cpanm:cpanminusをインストール
- Install dependencies:
cpanfileから依存モジュールをインストール - Run tests:テストを実行
fail-fast: falseの設定により、1つのバージョンでテストが失敗しても、他のバージョンのテストは続行されます。
ブランチ戦略との連携
ブランチ戦略に合わせて、トリガーを調整できます。
|
|
この設定なら、フィーチャーブランチへのプッシュでもテストが走ります。
プルリクエストでのテスト確認
プルリクエストを作成すると、自動的にワークフローが実行されます。
GitHubのプルリクエスト画面で、以下のように表示されます。
|
|
すべてのテストが通るまで、マージしないようにルールを設定することもできます。
バッジの追加とステータス確認
テストの状態を視覚的に表示するために、バッジ(ステータスバッジ)を追加しましょう。
README.mdにバッジを追加
README.mdの冒頭に、以下のようなバッジを追加します。
|
|
バッジのURL形式:
|
|
{owner}:GitHubのユーザー名または組織名{repo}:リポジトリ名{workflow-name}:ワークフローファイルのname:で指定した名前(今回はTest)
テスト結果の確認方法
GitHubのリポジトリページで、テスト結果を確認できます。
- Actionsタブ:すべてのワークフロー実行履歴
- プルリクエストページ:そのPRに関連するチェック結果
- コミットページ:各コミットのチェック結果
実行中のワークフローは、リアルタイムでログを確認できます。
失敗時のデバッグ
テストが失敗した場合、以下の手順でデバッグします。
|
|
-rオプションで、サブディレクトリも再帰的にテストします。
失敗したテストのログを確認し、以下をチェックします。
- 依存関係:必要なモジュールがインストールされているか
- 環境変数:CI環境特有の設定が必要か
- ファイルパス:相対パスの問題がないか
GitHub Actionsのログには、ステップごとに折りたたみ可能なセクションがあり、エラー箇所が見つけやすくなっています。
まとめと次回予告
自動テストでチーム開発が楽になる
今回は、GitHub Actionsを使ったCI環境を構築しました。
設定したこと:
- ワークフローファイルの作成(
.github/workflows/test.yml) - 複数のPerlバージョンでの並列テスト(マトリックス戦略)
- プッシュとプルリクエストでの自動実行
- ステータスバッジの追加
得られた効果:
- コードをプッシュするだけで、自動的にテストが実行される
- 複数のPerlバージョンでの互換性を確認できる
- チーム全員が、テストの状態を一目で把握できる
CIを導入することで、「テストを忘れた」「環境で動かない」という問題から解放されます。
TDDとCIの相乗効果
TDD(テスト駆動開発)とCI(継続的インテグレーション)を組み合わせると、以下の好循環が生まれます。
- TDDでテストを書く → 常にテストが存在する
- CIで自動実行 → テストの実行漏れがなくなる
- 早期にバグ発見 → 修正コストが低い
- 安心してリファクタリング → コード品質が向上
この流れが、チーム全体の開発速度と品質を高めます。
次回予告
次回は「MooによるTDD講座 #5 - 実践的なTDDテクニックとベストプラクティス」として、以下の内容を扱います。
- 実践的なTDDのワークフロー
- 効果的なテスト設計のポイント
- リファクタリングとテストの連携
- チームでTDDを推進するコツ
TDDをより深く理解し、現場で活用できるテクニックを紹介します。お楽しみに!