Visual Studio 2012

絶え間のない開発でのテスト

Larry Brader
Alan Cameron Cameron

 

Web アプリケーションは、ビジネス ニーズの変化や顧客のフィードバックに基づいて、数週 (または数日) ごとに更新、拡張されるのが一般的です。このように絶え間のない開発をサポートするには、開発サイクルのすべての側面を、従来の開発プロセスよりも効率的かつ軽量にする必要があります。たとえば、どんなに小さな変更を加えた場合でも、すべてをテストし直さなければならないというのが、ソフトウェアの性質です。しかし、完全な手動テストを数日ごとに繰り返すのは不可能です。つまり、手動の探索的テストとして開始した場合でも、最終的には自動テストにしなければなりません。今回は、絶え間のない開発を行う環境でのテストを、Microsoft Visual Studio 2012 がどのようにサポートするかについて説明します。

DevOps サイクル

ソフトウェア プロジェクトは、ソフトウェアを配置し、運用を開始した時点で終了するものではありません。関係者からのフィードバックを得、強化や拡張を計画し、最終的には新しいバージョンをリリースします。そこで、サイクルが再び始まります。このプロセスを DevOps サイクルと呼びます (図 1 参照)。

The Continuous Development Cycle
図 1 絶え間のない開発サイクル

従来のソフトウェア プロジェクトでは、各サイクルに数年かかります。通常、初回のリリースは、豊富な機能を備え、DVD で提供され、ユーザーのローカル コンピューターにインストールされます。これとは対照的に、最新 Web アプリケーションは、初回のリリースで最小限の機能を提供し、拡張や強化を数週 (または数日) ごとにリリースします。

たとえば、ソーシャル ネットワーキング サイトのマネージャーは、顧客の使い方を観察しながら、1 週間かけて新機能を試してみます。この試行期間の終わりには、機能のしくみを細かく調整します。

この非常に回転の速いサイクルでは、開発チームが DevOps サイクルを全体的なプロセスと見なすことが重要です。具体的には、ループの進捗を妨げる障害を取り除きながら、サイクルの各アクティビティの効率を上げる必要があります。

今回説明するテスト プロセスの強化がすべて目的とするところは、DevOps ループの循環にかかる時間の短縮です。特に、ここで紹介する新しいツールと手法は、今まで DevOps ループでテスト作業が引き起こしてきたボトルネックを減らすことを目的としています。

DevOps サイクルでのテスト

テストの重要な役割は、ユーザーのストーリーとその他の要件が実装されていることを実証することです。この最も効果的な方法が、アプリケーションを手動で実行して、各ストーリーをエンドユーザーと同じように行うことです。経験豊富なテスト担当者は、バグを明らかにするためにさまざまな戦略を当てはめ、アプリケーションの動作のあらゆるバリエーションとエッジ ケースを調べます。

アプリケーション コードが変更された場合は、アプリケーション コードに依存していると思われるすべてをテストし直すのが賢明です。通常、ソフトウェアの依存関係は複雑で、更新の主目的とは関係ないように見える機能にバグが現れるのが一般的です。したがって、従来の開発チームの本音を言えば、作成とテストが完了したコンポーネントを変更したくありません。冒頭で述べたように、わずかに変更を加えた場合ですら完全にテストし直さなくてはならないため、すべてを手動でテストすると、多くの労力やリソースが必要になります。

これとは対照的に、絶え間のない開発特有の短いサイクルでは、機能を強化および拡張するたびに、ソフトウェアの各部分を頻繁に再確認する必要があります。数日ごとにすべての機能を手動で再テストするのは不可能なので、短いサイクルでは、自動テストが必要になります。つまり、手動テストをプログラム コードに置き換えます。その結果、コード化されたテストを、すばやく、任意の頻度で実行できます。

では、絶え間のない開発を行うチームは、あらゆるテストをコードにして、手動テストをすべて放棄すべきでしょうか。このようなアプローチが提案される場合もありますが、実際には、以下のような効率的な妥協案があります。

新しいストーリーや、大幅に変更されたストーリーは手動でテストします。各テストに一貫して合格したら、そのストーリー用に自動化したバージョンのテストを作成します。結果として、製品を拡張するごとに、テストの総数が徐々に増加しますが、手動テストを比較的新しい機能のみに行うため、手動テストの負荷は一定のままです。

実際、絶え間のない開発を行う一般的なプロジェクトでは、コード化されるテストのほとんどは単体テストです。単体テストは、アプリケーション コードと共に記述されていて、アプリケーション全体の動作ではなく、ソフトウェア内部の個別のコンポーネントをテストします。このテストは、コード ベースが更新される際に安定性を維持するのに大いに役立ちます。

図 2 は、手動テストから自動テストへの段階的移行と、それに伴って拡張する単体テストとアプリケーション コードを示しています。これはあくまで理想図で、実際には、ほとんどのチームは部分的に手動テストを自動化しています。Visual Studio 2012 (およびその他のバージョン) は、部分的な自動化もサポートします。これにより、コードを記述せずにテストを高速化できます。

Ideal Transition from Manual to Automated Tests over Time
図 2 手動テストから自動テストへの理想的な段階的移行

Visual Studio 2012 でのテスト

Visual Studio 2012 と、その関連製品の Visual Studio Team Foundation Server (TFS) や Microsoft Test Manager (MTM) では、テストはどのようにサポートされているのでしょう。

アプリケーション全体のテストを専門としている方なら、MTM によるサポートに興味を持ち、開発者の方は、Visual Studio 2012 の自動テストのサポートに関心を持つと思いますが、絶え間のない開発ではこれら 2 つの役割が密接に関係し、中には区別をまったくなくすチームもあります。したがって、Visual Studio 2012 のツールは、さまざまなスタイルのテストを統合するよう設計されており、古典的なアプローチから絶え間のない開発まで、幅広いテスト プラクティスをサポートします。

Visual Studio 2012 での自動テスト

自動テストには、プログラム コードの記述または生成によって定義される、すべての種類のテストが含まれます。自動テストは Visual Studio 2012 で作成しますが、それをデバッグのために最初に実行するのも Visual Studio 2012 です。

テスト (およびテストが対象とするアプリケーション コード) が正しければ、アプリケーション コードと共に、そのテストをチェックインします。テストは、ビルド サービスによってソース コード リポジトリから取り出され、チームのビルド定義に従って定期的に実行されます。

単体テストと統合テスト: 単体テストは、アプリケーションに連続的な変更を行ってもバグが発生しないようにコードベースを維持する、最も効果的な方法の 1 つです。

単体テストは、アプリケーションのメソッド、クラス、または大きなコンポーネントを、アプリケーションの別の部分、外部システム、および外部リソースから切り離した状態でテストする方法です。実際には、開発者は「統合テスト」を作成するのがほとんどです。これは、単体テストと同じ方法で作成しますが、外部データベース、Web サイトなどのリソースに依存するテストです。どちらのテストでも、同じツールとインフラストラクチャを使用します。

Visual Studio 2012 では、NUnit、xUnit、既定の VSTest など、複数のテスト フレームワークのいずれかを使用するテストを作成できます。これらのフレームワークのいずれかでテストをコード化したら、[テスト エクスプローラー] ウィンドウを開いて [すべて実行] を選択すれば、ウィンドウにテスト結果の概要が表示されます。

バックグラウンド テストは、ソリューションをビルドするたびにバックグラウンドでテストを効率的に実行するオプションです。変更によって影響を受けるテストを最初に実行します。つまり、作業をしながら、どのテストが合格または失敗したかを絶えず確認します。

フェイクによる単体の分離: 真の単体テストとは、テスト対象の単体を、依存しているコードから切り離すことを意味します。これには、多くのメリットがあります。単体が、依存している別の単体と同時に開発または更新される場合でも、別の単体が完了するのを待機しないでテストできます。この単体を別の方法または別のアプリケーションで使用するために、アプリケーションを再構築する場合も、テストを変更する必要はありません。

Visual Studio 2012 には、単体を依存関係から切り離すための 2 つのメカニズムがあり、まとめて "フェイク" と呼びます。境界の外で行う、単体からメソッドへの呼び出しは、少量のコードを提供することで処理します。たとえば、shim を定義して、DateTime.Now などの外部メソッドへの呼び出しをインターセプトできます。shim からは常に同じ応答を受け取るため、単体は、呼び出されるたびに同じ動作を行います。また、スタブを定義すれば、まだ読み込まれていないアセンブリに、メソッドのプレースホルダー実装を提供できます。

パフォーマンス テストとロード テスト: Visual Studio 2012 Ultimate は、パフォーマンス テストとストレス テストに固有のテスト機能を提供します。特定の負荷をかけた状態でのパフォーマンスを測定するために、アプリケーションをインストルメント化して実行することができます。Web アプリケーションは、多数のユーザーのシミュレーションを行いながら、複数の要求で実行できます。

コード化された UI テスト: コード化された UI テストによって、アプリケーションを実行し、その UI を操作するコードを生成できます。Visual Studio 2012 には、コード化された UI テストの作成および編集に特化したツールが搭載されているだけでなく、コードに対して独自に編集や追加を行うことも可能です。たとえば、Web サイトで何かを購入するという簡単な手順を作成したら、コードを編集して、多数の商品を購入するループを追加できます。

コード化された UI テストは、Web ページなど、UI に検証などのロジックがある場合に特に便利です。コード化された UI テストは、UI の単体テストや、アプリケーション全体用の統合テストとして使用できます。

Microsoft Test Manager での手動テスト

計画されたテスト、または探索的テストを、手動で実行できます。手動テストは、MTM を使用して実行します。テストは、通常、チェックインしたコードから構築されているバージョンのアプリケーションで実行されます。

手動テストは、ユーザーのストーリー (または、製品バックログ項目やその他の要件) にリンクされるのが一般的で、テストの結果は、プロジェクト ダッシュボードのレポートに表示されます。つまり、どのストーリーが正常に実装されたかを、だれもが簡単に確認できます。

探索的テスト: 探索的テストの目的は、アプリケーションを試しに実行してみることです。では、このテストを実行するのに MTM が必要なのはなぜでしょう。

MTM では、作業中の操作、コメント、画面ショットを記録できます。バグ レポートを作成する場合、この情報がすべて自動的にレポートに追加されるので、バグを再現する方法についての正確な説明を追加する必要がなくなります。図 3 は、テスト対象の Web アプリケーションと並べて表示されている MTM 探索テスト ウィンドウの例です。

Recording a Screenshot and Making Notes in the Exploratory Testing Window
図 3 探索的テスト ウィンドウでの画面ショットの記録とメモの追加

MTM では、アプリケーション自体をクライアントとサーバーの両方でインストルメント化して、アプリケーションのデバッグに使えるイベント データを記録することも可能です。このデータは、バグ レポートに自動的に追加されます。

バグが修正されたら、修正について検証するために、探索で行ったステップを繰り返しますが、このために、探索セッションからテスト ケースを生成し、関連するステップを含めることができます。

テスト ケースを含む計画されたテスト: テスト ケースは、テスト担当者が実行する一連のステップとして定義する手動テストです。図 4 は、テスト ケースで定義されているステップを示しています。

Defining Steps and Expected Results in a Test Case
図 4 テスト ケースのステップと想定結果の定義

テスト ケースによって、ユーザーが必要とするものが明確になります。ステップを使用すれば、スプリントの始めにユーザーおよびその他の関係者とストーリーや要件について話し合う際、スプリントの最後までにユーザーが何をできるようになっているかを正確に示すことができます。各テスト ケースは、要件の一例に過ぎないので、各要件は、1 つ以上のテスト ケースと関連付けられることがほとんどです。たとえば、アイスクリームを購入できるようになることが要件なら、1 つのテスト ケースに、特定の味を購入するためのステップを設定します。ミックスされた味を購入することを記述するのであれば、別のテスト ケースを作成します。関係者との話し合いの基本理念は、「これらのテスト ケースを正常に実行できたら、ストーリーの実装を検討する」とするべきです。

TFS では、ストーリーや要件、さらにテスト ケースを作業項目によって表現します。テストの結果から要件の進捗を追跡できるように、それらを相互にリンクすることができます。

テスト ケースを実行する際、ステップは画面の片側に表示されます。アプリケーションを実行しながら、各ステップをチェックします。最後に、テストに合格したか失敗したかをチェックします。

探索的テストと同様、操作、コメント、画面ショット、アプリケーション データが記録されるので、詳細なバグ レポートを非常にすばやく作成できます。

ステップを使用する大きなメリットは、アプリケーションに詳しくない担当者でもテストを確実に繰り返せることです。テストを繰り返せば、合格または失敗という結果の理由は、テストが単に最後の実行時とは異なって実行されていたからだけではないという確信を持つことができます。

探索セッションから、計画されたテスト ケースを生成することもできます。これにより、常に同じ動作を使用してテストを実行できるようになります。

手動テストを自動化する

手動テストの大部分を自動化することは、DevOps サイクルでテストにかかる時間を最小限にするために不可欠です。Visual Studio 2012 は、この自動化を複数の方法でサポートします。

記録/再生: テスト ケースを半自動で再実行できます。テスト実行の 2 回目以降、MTM は、初回の実行で使用されたキーストロークやジェスチャーを再生します。結果が、ステップで詳述されている想定と一致するかどうかを検証するだけでかまいません。

再生によって、手動テストの速度や信頼性が高まります。アプリケーションに完全には精通していない同僚にテストを任せ、負荷を分散することも可能になります。

テストを完全には自動化しなくても、すばやく、信頼性の高い再生によって、DevOps のサイクル時間が短くなります。この機能を使うために Visual Studio 2012 をインストールする必要はなく、コードを記述する必要もありません。

コード化された UI テストの生成: 記録された手動テスト ケースの実行から、完全に自動化された、コード化された UI テストを生成できます。生成されたコードは、手動テストと同じ動作を実行します。Visual Studio 2012 の特殊なエディターを使用すると、結果を検証するためにテストを拡張して、異なる入力データに対して繰り返すように汎用化することもできます。この特殊なエディターを図 5 に示します。

Editing UI Actions in Visual Studio 2012
図 5 Visual Studio 2012 での UI 操作の編集

テスト メソッドへのテスト ケースの関連付け: テスト ケースは、テスト実行から生成されていないものであっても、あらゆるテスト メソッドに関連付けることができます。テスト実行の結果は、まるで手動でステップを実行したかのようにレポートされます。テスト ケースは、手動テストと動作は同じでも、UI を使用するのではなく直接ビジネス ロジックを実行する統合テストに関連付けるのが一般的です。

このアプローチには、UI レイアウトの変更がテストを無効にしないというメリットがあります。また、開発チームが、適切な統合テストを既に作成している場合に便利です。

Lab Management

アプリケーションをテストする際、まず必要になるのがテストを実行するコンピューターです。実のところ、現在では複数台のコンピューターを必要とするアプリケーションがほとんどです。現実的なテスト環境を構築するためには、たとえば、Web サーバー、データベース サーバー、クライアント ブラウザーを別個のコンピューターにインストールする必要があります。そのような環境を図 6 に示します。

A Sample Lab Environment for Testing a Sales Web Site
図 6 販売 Web サイトをテストするためのサンプル ラボ環境

基本的なインストールに加え、「探索的テスト」のセクションで説明した、イベント データを収集できるエージェントもインストールします。

MTM では、ラボ センターという機能によって、これらの作業がすべて簡単になります。ラボ センターでは、ラボ環境を定義できます。ラボ環境は、テスト目的でグループとして使用される一連のコンピューターです。

ラボ センターは、コンピューターの割り当て (つまり、他の開発者のテストが実行されているコンピューターを誤って使うことがありません) に加え、必要なテスト エージェントもインストールしてくれます。ラボ センターでは、環境内のどのコンピューターにもすばやくログインできるコンソールが用意されています。

ラボ センターは、仮想マシン (VM) を作成および管理する場合にも便利です。仮想環境を作成し、関連するプラットフォーム ソフトウェアをインストールしたら、そのライブラリのコピーを保存できます。このコピーは、アプリケーションをテストする際にいつでも使用できます。環境のクリーン コピーのインスタンスを再作成して、アプリケーションのコンポーネントの新しいバージョンをインストールするだけでかまいません。この配置プロセスを自動化することもできます。

ラボ センターの使用、特に、VM の機能の活用により、ラボを管理する従来のアプローチと比べて大幅にラボのセットアップ時間を短縮できます。ラボ センターは、各 DevOps サイクルにかかる時間を短縮するのに大きく役立ちます。

TFS での自動テスト

自動テストは、最初に、開発者のコンピューター上の Visual Studio 2012 で実行されます。コードがソース リポジトリにチェックインされたら、ビルド サービスは、さまざまな方法で、統合されたコードのテストを実行することができます。

定期ビルド: ビルド サービスによって、コードがコンパイルされ、テストが実行されます。ビルド定義を作成すれば、実行するテストを指定できます。また、テストを実行するタイミングを指定することもできます。たとえば、中核となる一連のテスト定期的に実行し、負荷の高いテストを毎晩実行することもできます。

ビルドの結果は、Visual Studio 2012 でも、プロジェクトの TFS Web サービスでも確認できます。エラーについて通知する電子メールを受け取ることもできます。

ラボ配置: 前述のとおり、ラボ センターを使うと、一連のラボ コンピューターをテストに割り当てることができます。ラボのビルドを定義すれば、このプロセスを自動化できます。コードがチェックインされたときや、1 日の特定の時間に、ビルドがトリガーされるとします。ビルドは、最初に、すべてのアプリケーションとテスト コードをコンパイルします。これが成功すると、ラボ環境が割り当てられ、それが仮想環境であれば、初期状態に戻すことも可能です。その後、アプリケーション コンポーネントが適切なコンピューターに配置され、指定されたクライアント コンピューターにテストがインストールされます。テストは、そのコンピューターからアプリケーションを実行します。

テストは、どの種類の自動テストにしてもかまいませんが、この種類のビルドは、大規模な統合テストや、アプリケーション全体のテストの実行に使用するのが一般的です。

テストがテスト ケースと関連付けられている場合、結果は、関連するユーザー ストーリーか要件に対して記録され、プロジェクトの進捗レポートに表示されます。

レポート

TFS は、プロジェクトの進捗を示すさまざまなグラフや表を提供します。これらは、個別に表示することも、プロジェクト ダッシュボードに表示することもできます。テストに関連するレポートもあります。

たとえば、図 7 のユーザー ストーリー テスト状態レポートでは、現在のスプリントで作業中のストーリーの一覧が示されます。グラフでは、ストーリーごとに実行される開発作業と、関連テストの成功や失敗も示されます。テストの実行中に失敗が検出されたら、結果として生成されるバグ レポートも、要件に関連付けられます。

図 7 ユーザー ストーリーのテスト状態レポート

  作業の進捗 テスト状態
タイトル 完了率 (%)  

残り

時間

テスト

ポイント

テスト結果 バグ数
顧客がアイスクリームを購入できる。 60%         16 3 67% 33% 3
顧客がカタログから味を選択できる。 60%         10 3 67% 33%  
メーカーが味のカタログに変化を持たせることができる。 25%                 15 2 100%  
メーカーが、味によって価格を変えられる。 39%             23 2 100% 4
顧客が、お気に入りの味を設定できる。 100% 0 1 100% 4
ユーザーが、お気に入りの味を英国英語で表示できる。 100% 0 6 50% 33%      
顧客が、好きな種類のコーンを選べる。 75%       5 22 63% 26%     2
                                     

グラフの結果は、最後に実行された手動テストと、自動テストの実行の両方が混在しています。

図 8 のテスト計画の進行状況レポートでは、現在のスプリント向けに作成されたテスト ケースの数と、実行されたテスト ケースの数が示されます。

Test Plan Progress Report for a Sprint
図 8 あるスプリントのテスト計画の進行状況レポート

チームによっては、各スプリントの開始時にテスト ケースを作成することを好む場合もあります。すべてのテストは、スプリントの最後には緑色になります。

Visual Studio 2012 と絶え間のない開発

単体テストからアプリケーション全体の手動テストまで、Visual Studio 2012 のさまざまなテスト機能についていくらか理解していただけと思います。

DevOps サイクルでは、開発はプロセスの半分でしかなく、運用からのフィードバックを組み込むことも必要です。DevOps サイクルの長さは状況によってまちまちです。原子力発電所を開発していれば、ループはおそらく非常にゆっくりと進み、Web アプリケーションを実行していれば、数日単位にループが繰り返されます。ゆっくりとしたサイクルも、回転の速いサイクルも、さまざまなシステムに等しく有効で、適切です。どちらも、程度の差こそあれ、テストを必要とするのは変わりません。絶え間のない開発の回転が速いサイクルがプロジェクトに適しているなら、ループ内のあらゆる動作の実行時間を減らすことが重要です。また、規則的なペースで活動するプロジェクトと比べて、開発者とテスト担当者の役割の境界線を目立たなくすることもおそらく必要です。

Visual Studio 2012 のツールによって、アプリケーションのテストにかかる時間を大幅に短縮できます。覚えておきたいポイントは、次のとおりです。

  • クリーンなラボ環境は、特に VM を使用することで、迅速かつ自動的にセットアップできます。ラボ センターを活用してください。
  • 探索的テスト、および計画されたテスト中の記録動作によって、信頼性の高いバグ レポートをすばやく作成でき、だれかが再現しようとした結果バグが消えるという可能性が少なくなります。
  • 手動テストから自動テストへの段階的移行を実装できます。自動テストは回帰テストの大部分に対処するのに対し、手動テストは新しいストーリーや更新されたストーリーに重点をおきます。
    • 探索的テストから、繰り返し可能な手動テスト ケースを生成できます。
    • テスト実行を記録して、それらをすばやく、確実に再生できます。
    • テスト実行から、コード化された UI テストを生成できます。または、単独でコード化された統合テストを、テスト ケースに関連付けることができます。

図 9 は、探索的テストから自動テストへの工程を示しています。
Test Progression
図 9 テストの進捗

  • テスト ケースは、ユーザー ストーリーを正確に表すのに役立ちます。関係者と共同でステップを記述すれば、ストーリーの内容に関する意見の相違を減らすことができます。
  • テストは、要件 (または、ユーザー ストーリーか製品バックログ項目) と関連付けられています。このため、完了した作業の観点だけではなく、成功したかどうかという観点に基づき、ユーザーのニーズの実装状況に関する包括的なレポートを参照できます。テストによって、各スプリントで、開発チームに目標が提供されます。
  • テスト ケースと要件は、PowerPoint のストーリーボード、要件ドキュメント、または統一モデリング言語モデルに関連付けることができます。ストーリーボードに変更を加える場合は、テストへの必要な変更をトレースできます。
  • テスト計画は、テスト ケース、コード、要件、テスト環境、テスト設定、チーム プロジェクトをまとめて関連付けます。チームが、製品を拡張するために再び集結する前に、別のプロジェクトに数か月取り掛かっていたとしても、テストに必要なものをすべて簡単に再構築できます。

Visual Studio 2012 が DevOps サイクルにどのように適しているかについて、概要を説明しました。テスト作業に合理化されたアプローチが必要な理由と、この目的を達成するために Visual Studio 2012 が提供するツールについて理解していただけたと思います。詳細については、MSDN ライブラリの「Testing for Continuous Delivery with Visual Studio 2012 RC」(Visual Studio 2012 RC での継続配信のテスト) を bit.ly/KHdOq4 (英語) から参照してください。このページは、Visual Studio 2012 によって提供されるテスト インフラストラクチャのすべての側面を扱った詳細ガイドです。関連記事には、「Verifying Code by Using Unit Tests」(単体テストを使用してコードを検証する、bit.ly/dz5U3m、英語) や「Testing the Application」(アプリケーションをテストする、bit.ly/NbJ01v、英語) などがあります。

Larry Brader は、ここ数年間にわたって、Microsoft patterns & practices チームのシニア テスト担当者として活動してきました。以前は、軍部および医療向けテクノロジの分野で開発者、テスト担当者を務めていました。

Alan Cameron Wills は、マイクロソフトの開発部門でプログラミング ライターを務めています。以前は、開発者やソフトウェア アーキテクトとして活動していたほか、開発メソッドに関するコンサルティングも行っていました。

この記事のレビューに協力してくれた技術スタッフの Howie Hilliker、Katrina Lyon-Smith、Peter Provost、Rohit Sharma に心より感謝いたします。