継続的インテグレーション

より迅速なフィードバックでチームのアジリティを構築します。テストより速くは進めないから。

Dan Radigan 作成者 Dan Radigan
トピック一覧

継続的なインテグレーション (CI) へチームがコミットすることが、アジリティを手に入れる近道です。それは(特にチームが未だ CI を受け入れていない場合)脅迫的に聞こえるかもしれません。しかし、いいニュースもあります。コードベースの継続的なインテグレーションも自動化テストフレームワークも、利用しているテクノロジーに関わらず、実践できる可能性があるのです。

継続的インテグレーションとは

継続的なインテグレーションは、コードの変更をリポジトリのメイン ブランチに定期的に統合して変更のテストを早期かつ頻繁に行う、アジャイルDevOps のベスト プラクティスです。開発者は毎日、あるいは 1 日複数回、コードを統合するのが理想的です。

継続的インテグレーションのメリット

CI に時間を割くと、コード変更の際のフィードバックが速くなります。「数分」で済むほど速くなります。主に手動テストに依存しているチームは、数時間でフィードバックを得られる可能性はあります。しかし現実には、包括的なテストのフィードバックはコード変更を行ってから、1 日から数日かかります。そのころまでには、さらに変更が発生しており、単なるバグの修正が面倒な発掘調査になってしまうでしょう。開発者が問題の根本を探すために、何層にも及ぶコードを掘り下げなければならないからです。

これでは速いわけがありません

継続的ビルドとテストの自動化で品質を保護する

わたしたちのうち何人が、最新のソースコードをダウンロードして、コンパイルされていないことに気づいたり、重要なバグに気づいたりしてるでしょう?何と生産性の悪い!

以下の 2 つのことを実践してこの状況から脱出できます。

継続的なビルド:変更したらすぐにプロジェクトを作成する。理想的なのは、各ビルド間における変更セットを 1 つまでとすること。

テストの自動化:品質を保証するためのソフトウェアのプログラム検証。テストはソフトウェアの UI (このあとすぐに説明します)またはバックエンドのサービス層から開始できます。

この 2 つの実践はピーナツバターとジャムだと思ってください:別々でもおいしい、一緒でもおいしい!継続的インテグレーションにより継続的なビルドとテストの自動化を組み合わせ、各ビルドで確実にコードベースの品質も評価できるようになります。

忘れないでください。利点を十分に有効活用するためには、チームは直ちに開発を中断して破損に対処する、という規律を身に付ける必要もあります。ビルドが壊れた状態で放置されていては、チームがテストの作成と自動化の構成に費やすエネルギーは無駄になります (ミスを犯さずにエネルギーを費やすこと。これが投資です)。CI への投資を保護することとコードベースの品質を維持することは同じことなのです。

CI でのテスト: ユニット、API、機能テスト

CI の実行には 2 つのフェーズがあります。ステップ 1 ではコードのコンパイルを確実に行います (あるいは、インタープリター型言語の場合はすべてをひとつにまとめます)。ステップ 2 では、コードが設計通りに機能するか確認します。最も確実なのは、製品のすべてのレベルを検証できる一連の自動化テストを実施することです。

ユニットテスト

ユニットテストは、コードの中でもコアコンポーネントに極めて近いところで実行します。品質を保証する防御の第一線となります。

メリット: 簡単に作成できて速く実行でき、コードベースのアーキテクチャに近いモデルです。

デメリット: ユニットテストではソフトウェアのコアコンポーネントしか検証しません。つまり、一緒に稼働する複数のコンポーネントを含めたユーザーワークフローを反映していません。

ユニットテストはコードの動作を明確にするため、開発者はコードのその部分の最新状況をユニットテストからレビューできます。

API テスト

良いソフトウェアとはモジュール式で、複数のアプリケーションにまたがる作業を明確に分別できます。API は複数の異なるモジュールがそれぞれ通信し合うエンドポイントであり、API テストはひとつのモジュールから他のモジュールへとコールすることで検証を行います。

メリット: 一般的に作成が簡単で、速く実行でき、アプリケーションのそれぞれの相互作用を作成するのが容易です。

デメリット: コードの簡易なエリアでは、API テストが複数のユニットテストの再現になってしまうことがあります。

API はアプリケーションのパーツ間のインターフェースであるため、リリースの準備の際には大変便利です。リリースしようとしているビルドが一旦すべての API テストをパスすれば、顧客向けの出荷に相当な自信が持てます。

機能テスト

機能テストは、コードベースとモジュールのユーザーワークフローのより大きな範囲をテストします。ウェブアプリケーションでは、たとえば、HTTPUnitSelenium なら、ユーザーインターフェースと直に相互作用して製品をテストできます。

メリット: ユーザーアクションを模倣して、複数コンポーネントの相互運用性をテストできるため、バグをより見つけやすくなります。

デメリット: ネットワークの待ち時間やスタック技術の瞬時停止などにより、ユニットテストよりも遅く、検出漏れが報告されることもあります。

実際のユーザーワークフローに近づくにつれ、自動化テストのスピードが落ちていくことがあります。HTTPUnit は、本格的なウェブブラウザではないため、より速く実行できます。Selenium は、ウェブブラウザと同じ速度でしか実行できませんが、複数のウェブブラウザで並行して実行できる利点があります。このような難点もありますが、機能テストは極めて有益なうえ、人為テストよりも断然速くフィードバックを提供してくれます。

そういえば…

テスターの中には、自動化テストを己の存続を脅かす存在と受け取る人もいるかもしれません。これは短絡的で、全くもって事実とは異なる思考です。単調な繰り返しテストの作業から解放され、テスターはリスク分析、テストのプランニング、他のスキル(コードを学ぶとか!)を磨く時間を費やすことができるのです。

継続的インテグレーションを高速に

Atlassian では、開発者を常にイノベーティブに保ち、コードベースは健全に保つ努力をしています。開発者の「内部フィードバック ループ」– 変更を作成してからテスト結果を取得するまでの所要時間 – 短縮を重要視しています。

自動化テストの実行により、ビルドの追加や期間の延長が可能です。戦略のひとつは、複数のサーバーまたは「ビルドエージェント」にまたがって自動化テストを並行して実施することです。そうすれば、CI サーバーで実際に 2 件、20 件、たとえ 200 件でも同時にテストを実行できるのです。クラウド技術を使用すれば、テストパッケージが大きくなるのに合わせ、開発チームのニーズに見合ったスケールへと CPU を容易に拡張できます。ですが、CPU は無制限ではありません。コードの各エリアを重複しない様に完全にテストします。重複テストはビルド期間を長引かせます(CPU も無駄に使用します)。エンジニアが早くゴーサインを得られれば、バックログの次の項目へ早く進むことができます。

ブランチングと CI:理想的な組み合わせ

マージが厄介であるゆえに、多くのチームがブランチングを避けています。Git のような新しいバージョン管理テクノロジーを使用すれば、ブランチングもマージも簡単になります。確実にプライマリのコードライン (Git 用語でいう「main」) を健全に保つには、開発全般で同じレベルの継続的インテグレーションと安定したバージョンのブランチを同様に実行します。ビルドがブランチに送られれば、チームは確実にコードのアップストリームへマージできます。

ブランチング、継続的インテグレーション、テストの自動化を行えば、コードの品質を維持しつつ、生産的かつ革新的なチームを実現できます。次の段階へ進む準備ができたら、CI を開始するためのステップバイステップガイドをご覧ください。

最高のアジャイル開発とは、定期的に実用的なソフトウェアをデリバリーし、技術的負債を最小限に抑え、創意工夫に妥協しないことです。

次の記事
デザイン