継続的インテグレーションを開始する方法

5 つのステップで継続的なインテグレーションと自動テストを採用する方法について説明します。

Sten Pittet Sten Pittet

継続的なインテグレーション (CI) は、開発者のチームが多くの場合はメイン ブランチまたはコード リポジトリに早い段階で自分のコードを統合するプラクティスです。目標は、プロジェクトまたはスプリントの終了を待って、すべての開発者の作業をマージすることによって「統合地獄」を見るリスクを軽減することです。

CI を採用する主なメリットの 1 つは、競合を早期に特定して対処することで、開発サイクル中の時間を節約できることです。また、テスト スイートの改善に重点を置くことによって、バグやリグレッションの修正に費やす時間を短縮できる素晴らしい方法です。最後に、コードベースと顧客向けに開発している機能についての理解を共有しやすくなります。

継続的なインテグレーションへの移行の最初のステップ: 自動テストを設定する

自動化テストを開始する

さまざまな種類のテストを理解する

CI のメリットを最大限に活用するには、メインリポジトリに加えられたすべての変更に対してテストが実行されるように、テストを自動化する必要があります。メインブランチのみにテストを集中させるのではなく、リポジトリのあらゆるブランチでテストを実行することを強く勧めます。そうすることで問題を早期に発見でき、チームの混乱を最小限に抑えることができます。

実装されたテストには多くの種類がありますが、開始したばかりの場合はすべてを一度に実行する必要はありません。単体テストで小規模から始めて、時間をかけてカバレッジを拡張できます。

  • 単体テストは範囲が狭く、通常は個々のメソッドまたは機能の動作を検証します。
  • 統合テストは複数のコンポーネントが全体として正常に動作することを確認します。他のサービスとの統合をテストすると同時に、このテストにはいくつかのクラスが関与する場合があります。
  • 受け入れテストは統合テストに似ていますが、コンポーネント自体ではなくビジネス ケースに焦点を当てています。
  • UI テストは、アプリケーションが正しく機能することをユーザーの視点から確認します。

すべてのテストが同等ではありません。Mike Cohn が作成したテストのピラミッドではトレードオフが視覚的に表現されています。

トライアングルのテスト

単体テストはほとんどがコードのごく一部をチェックしているため、迅速で安価に実装できます。一方、UI テストは実装が複雑です。ブラウザやモバイルの動作をエミュレートするための複数のサービスだけでなく、多くの場合は完全な環境を起動する必要があるため、実行が遅くなります。そのため、複雑な UI テストの回数を制限して、基本的には優れた単体テストを活用して素早くビルドを行い、できるだけ早く開発者にフィードバックを提供できます。

テストの自動実行

継続的なインテグレーションを採用するには、メイン ブランチにプッシュ バックされるすべての変更でテストを実行する必要があります。そのためには、リポジトリを監視してコードベースへの新しいプッシュをリッスンできるサービスが必要です。オンプレミスと Cloud の両方から選択できるソリューションは数多くあります。サーバーを選択するには、次の点を考慮する必要があります。

  • あなたのコードはどこでホストされていますか? CI サービスはコードベースにアクセスできますか? コードを置く場所について特別な制限はありますか?
  • アプリケーションに必要な OS とリソースは何ですか? お客様のアプリケーション環境はサポートされていますか? ソフトウェアをビルドしてテストするための適切な依存関係をインストールできますか?
  • テストに必要なリソースはどれくらいですか? Cloud アプリケーションによっては、使用できるリソースに制限がある場合があります。ソフトウェアが大量のリソースを消費する場合は、ファイアウォールと通して CI サーバーをホストできます。
  • あなたのチームには何人の開発者がいますか? チームが CI を採用すると、毎日多くの変更がメイン リポジトリにプッシュされます。開発者が迅速なフィードバックを得るためには、ビルドのキュー時間を減らす必要があり、適切な同時実行性を提供するサービスまたはサーバーを使用したくなるでしょう。

かつては通常、Bamboo や Jenkins のような別の CI サーバーをインストールする必要がありましたが、今ではクラウドでより簡単に採用できるソリューションを見つけることができます。たとえば、コードが Bitbucket Cloud でホストされている場合は、別サーバーやビルドエージェントを構成しなくても、リポジトリのパイプライン機能を使用してすべてのプッシュでテストを実行でき、並行処理についての制限も発生しません。

image: node:4.6.0 pipelines:   default:     - step:         script:           - npm install           - npm test

Bitbucket Pipelines で Javascript リポジトリをテストする場合の構成例。

コードカバレッジを使用してテストされていないコードを探す

自動テストを採用したら、テスト カバレッジ ツールと組み合わせることをお勧めします。これによって、コードベースがどれぐらいあなたのテスト スイートによってカバーされているかを把握できます。

80% 以上のカバレッジを目指すのはよいことですが、カバレッジの割合が高いこととテストスイートが優れていることを混同しないように注意してください。コードカバレッジツールはテストされていないコードを見つけるのに役立ちますが、最終的に違いを生むのはテストの品質です。

始めたばかりであれば、慌ててコードベースの 100% カバレッジを達成する必要はありませんが、テスト カバレッジ ツールを使用して、まだテストが設定されていないアプリケーションの重要な部分を見つけてそこから開始してください。

リファクタリングはテストを追加する機会です

アプリケーションに重要な変更を加えようとしている場合は、影響を受ける可能性のある機能の周りに受け入れテストを記述することから始めてください。これによって、コードのリファクタリングや新機能の追加後に元の動作が影響を受けないように、セーフティ ネットが提供されます。

継続的インテグレーションを導入する

テストの自動化は CI の重要な部分ですが、それだけでは不十分です。チーム文化を変えて、開発者が何日もメイン ブランチに変更をマージすることなく機能を取り扱わずにいる必要がある場合があります。また、グリーン ビルドの文化を実施する必要があります。

早期に頻繁に統合する

トランクベース開発またはフィーチャー ブランチのいずれかを使用している場合でも、開発者はできるだけ早くメイン リポジトリに変更を統合することが重要です。ブランチや開発者ワークステーションにコードを長く置きすぎると、メイン ブランチにマージすることを決めたときになって確認が必要な競合が多すぎるというリスクが発生します。

早期に統合することで、変更の範囲を縮小して競合発生時に競合を把握しやすくなります。もう 1 つのメリットは、変更がより理解しやすくなるので開発者間で知識を共有しやすくすることです。

既存の機能に影響を与える可能性のある変更を自分で行う場合は、機能フラグを使用して作業が完了するまで本番環境での変更をオフにできます。

ビルドを常に緑色に保つ

開発者がメイン ブランチのビルドを壊した場合は、その修正が主な優先事項になります。壊れている間にビルドに多くの変更が加えられると、何が壊れたかを理解することが難しくなります。また、より多くの障害を招くリスクもあります。

テスト スイートには時間をかける価値があります。早い段階でテスト スイートで障害が発生して開発者にフィードバックを与えることで、可能な限り早く変更がプッシュされるようになります。テストを分割することで、長期に及ぶテストに入る前に手早く実施できるテスト (単体テストなど) を実行できます。テスト スイートで障害が発生するまでに往々にして長時間かかる場合は、以前の作業に戻って修正するためにコンテキストを切り替える必要が生じてしまい、相当分の開発者の時間が無駄になります。

ビルドが壊れたときに開発者に警告が表示されるように通知を設定することを忘れないでください。また、メイン ブランチの状態をダッシュボードに表示して、誰でもそれを見られるようにすることも可能です。

ストーリーの一部としてテストを書く

最後に、開発されるすべての機能に自動テストがあることを確認する必要があります。開発が遅くなるように見えるかもしれませんが、実際は、チームすべてのイテレーションで導入されたリグレッションやバグを修正するために費やす時間が大幅に短縮されます。また、テスト スイートでは、以前に開発されたすべての機能が期待どおりに動作することを迅速に確認できるため、コードベースに自信を持って変更を加えられます。

良いテストを書くには、ユーザー ストーリーの定義に早い段階で開発者が関与していることを確実にする必要があります。ビジネス要件をよりよく共有してプロダクト マネージャーとの関係を促進するための、最高の方法です。テストを実行するコードを実装する前に、テストを書くことから始めることすら可能です。

バグ修正時にテストを書く

既存のコードベースを持っていても開始したばかりでも、リリースの一部としてバグが発生することは確かです。その解決時に、必ず再発防止用テストを追加してください。

CI は QA エンジニアが品質を改善できるようにする

CI と自動化の採用によって、QA エンジニアの役割も変わります。もはや QA エンジニアは、アプリケーションのちょっとした機能を手動でテストする必要はありません。今日では、開発者をサポートして適切なテスト戦略の採用をサポートするツールの提供に多くの時間を費やせます。

継続的なインテグレーションの導入を開始すると、QA エンジニアはより良いツールとデータセットによるテストの促進に注力できて、開発者がより良いコードを書く能力を向上させるのに役立ちます。複雑なユース ケースについてはまだいくつかの探索的テストがありますが、これは彼らの仕事の中であまり目立たないものになるはずです。

継続的インテグレーションの 5 つのステップ

これで、継続的なインテグレーションの背景にある概念をしっかりご理解いただけたと思います。ここでは、以下のように要約してみます。

  1. コードベースの重要な部分のテストを書き始めます。
  2. CI サービスを取得して、メイン リポジトリへのプッシュごとにこれらのテストを自動で実行します。
  3. チームが変更を毎日統合するようにします。
  4. ビルドは壊れたらすぐに修理します。
  5. 実装するすべての新しいストーリーのテストを書きます。

簡単に見えるかもしれませんが、効果的にするにはあなたのチームの真のコミットメントが必要になります。初めはリリースを遅くする必要があります。また、開発者が急いでテストなしで機能をリリースしないようにするためには、プロダクト所有者からの同意が必要になります。

管理が難しい可能性があるより複雑なテスト スイートの実装に移る前に、新しいルーチンに慣れるために小さなテストから始めることをお勧めします。