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

より迅速なフィードバックでチームのアジリティを構築します。テスト以上に迅速に動くことはできないからです。

Dan Radigan Dan Radigan
トピック一覧

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

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

継続的インテグレーションは、コードの変更をリポジトリのメインブランチに定期的に統合し、変更のテストをできる限り早期かつ頻繁に行う実行方法です。開発者は毎日、あるいは 1 日複数回、コードを統合するのが理想的です。

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

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

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

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

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

その状況から逃れるためのプラクティスは以下の 2 つです。

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

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

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

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

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

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

ユニットテスト

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

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

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

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

API テスト

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

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

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

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

機能テスト

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

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

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

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

話は変わりますが…

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

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

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

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

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

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

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

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

次の記事
Design