チュートリアル: マネージ コードに対する単体テストの作成と実行
このチュートリアルでは、ステップ実行作成して、一連の単体テストは、マネージ コードおよび Visual Studio の Microsoft の単体テスト フレームワークを使用してカスタマイズしてエクスプローラーをテストします。開発中の C# プロジェクトで作業を開始し、そのコードを実行するテストを作成し、テストを実行し、結果を調べます。次に、プロジェクト コードを変更し、テストを再実行します。
このトピックは、次のセクションで構成されています。
[!メモ]
このチュートリアルでは、マネージ コードについては、Microsoft の単体テスト フレームワークを使用します。テストのエクスプローラーは、テストのエクスプローラーのアダプターがある第三者に単体テスト フレームワークからテストを実行できます。詳細については、「方法: サードパーティ製の単体テスト フレームワークをインストールする」を参照してください。
[!メモ]
コマンド ラインからテストを実行する方法については、「チュートリアル : コマンド ライン テスト ユーティリティの使用」を参照してください。
必須コンポーネント
- Bank プロジェクト。「単体テストを作成するサンプル プロジェクト」を参照してください。
チュートリアルを準備します。
チュートリアルを準備するには
Visual Studio 2012 を開きます。
[ファイル] メニューの [新規作成] をポイントし、[プロジェクト] をクリックします。
[新しいプロジェクト] ダイアログ ボックスが表示されます。
[インストールされているテンプレート] の [Visual C#] をクリックします。
アプリケーションの種類の一覧の [クラス ライブラリ] をクリックします。
[名前] ボックスに「Bank」と入力し、[OK] をクリックします。
[!メモ]
"Bank" という名前が既に使用されている場合は、別のプロジェクト名を選択します。
新しい Bank プロジェクトが作成され、コード エディターに Class1.cs ファイルが開いた状態でソリューション エクスプローラーが表示されます。
[!メモ]
コード エディターに Class1.cs ファイルが表示されない場合、ソリューション エクスプローラーのファイル Class1.cs をダブルクリックして開きます。
ソース コードを 単体テストを作成するサンプル プロジェクト からコピーします。
Class1.cs の元の内容を、単体テストを作成するサンプル プロジェクト のコードで置き換えます。
BankAccount.cs としてファイルを保存します。
[ビルド] メニューの [ソリューションのビルド] をクリックします。
Bank という名前のプロジェクトができます。これには、テストするソース コードとテストに使用するツールが含まれています。Bank の BankAccountNS 名前空間には、パブリック クラス BankAccount が含まれます。そのメソッドを次の手順でテストします。
このすぐにのスタートでは、Debit のメソッドについて説明します。のメソッドは、通貨アカウントがバックトラッキングされ、次のコードが含まれているときに呼び出されます:
// method under test
public void Debit(double amount)
{
if(amount > m_balance)
{
throw new ArgumentOutOfRangeException("amount");
}
if (amount < 0)
{
throw new ArgumentOutOfRangeException("amount");
}
m_balance += amount;
}
単体テスト プロジェクトを作成します。
必要条件 : 「チュートリアルを準備する」の手順に従います。
単体テスト プロジェクトを作成するには
[ファイル] で、メニューの [追加] を選択し、[New Project ...] …]を選択します。
新しいプロジェクト]ダイアログ ボックスで、[インストール済み] を展開し、[Visual C#] を展開し、を [テスト] を選択します。
テンプレートの一覧で、を選択します [単体テスト プロジェクト]。
[名前] ボックスに、BankTest を入力し、を [OK] を選択します。
[BankTests] のプロジェクトは [銀行] のソリューションに追加されます。
[BankTests] のプロジェクトでは、[銀行] のソリューションへの参照を追加します。
ソリューション エクスプローラーで、[BankTests] のプロジェクトの SELECT [参照] は、コンテキスト メニューで [参照の追加...] を選択します。
参照マネージャー]ダイアログ ボックスで、[ソリューション] を展開し、[銀行] の項目をチェックします。
テスト クラスを作成します。
ここでは BankAccount のクラスを検証するためのテスト クラスが必要です。また、プロジェクト テンプレートによって生成された、ファイルを付け、さらにわかりやすい名前を使用するように UnitTest1.cs を使用できます。これは、ソリューション エクスプローラーでファイル名の変更が 1 ステップでもできます。
クラス ファイルの名前変更
ソリューション エクスプローラーで、プロジェクトの BankTests UnitTest1.cs ファイルを選択します。コンテキスト メニューから、[名前の変更] を選択し、BankAccountTests.cs にファイル名を変更します。コード要素 "UnitTest1" へのプロジェクトのすべての参照の名前を変更するかどうかを確認するダイアログの ○ を選択します。BankAccountTestに階段状このバリエーション クラスの名前。
BankAccountTests.cs ファイルの内容は次のコードが含まれています:
// unit test code
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace BankTests
{
[TestClass]
public class BankAccountTests
{
[TestMethod]
public void TestMethod1()
{
}
}
}
テスト対象のプロジェクトにステートメントを追加します
ここでは、クラスにステートメントを使用して、に完全修飾名を使用せずにテスト対象のプロジェクトに呼び出すことができるようにを追加できます。クラス ファイルの先頭に追加します:
using BankAccountNS
テスト クラスの要件
テスト クラスの最小要件があります:
[TestClass] の属性は、テストのエクスプローラーで実行する単体テスト メソッドを含むクラスにマネージ コードに Microsoft 単体テスト フレームワークに必要です。
移動テストのエクスプローラーにする各テスト メソッドは [TestMethod]の属性が必要です。
[TestClass] の属性を持たない、[TestMethod] の属性を持たないテスト クラスに他のメソッドを使用できます単体テスト プロジェクトの他のクラスがあります。テスト メソッドでこれらの他のクラスとメソッドを使用できます。
最初のテスト メソッドを作成します。
この手順では、BankAccount クラスの Debit のメソッドの動作を検証するために単体テスト メソッドを記述します。メソッドは、先頭にが表示されます。
テスト対象の解析メソッドで、はチェックする必要がある 3 文字以上の動作があると判断します:
メソッドは掛売金額がバランスを超える場合 [ArgumentOutOfRangeException] をスローします。
また、掛売金額がゼロより小さい場合 ArgumentOutOfRangeException をスローします。
チェックイン 1) .と 2.) が満足している場合、メソッドは残高から量を減算します。
最初のテストでは、このバランスが未満のゼロより大きい、有効な量 (1) アカウントから正しい量を引き出すことを確認します。
テスト メソッドを作成します。
BankAccountTests.cs ファイルに BankAccountNS; のステートメントを追加します。
BankAccountTests、そのクラスに次のメソッドを追加します:
// unit test code [TestMethod] public void Debit_WithValidAmount_UpdatesBalance() { // arrange double beginningBalance = 11.99; double debitAmount = 4.55; double expected = 7.44; BankAccount account = new BankAccount("Mr. Bryan Walton", beginningBalance); // act account.Debit(debitAmount); // assert double actual = account.Balance; Assert.AreEqual(expected, actual, 0.001, "Account not debited correctly"); }
メソッドは多少簡単です。また、先頭のバランスを持つ BankAccount の新しいオブジェクトを設定し、有効な量をバックトラッキングします。また、最終的な残高が、意図したとおりであるとマネージ コードの AreEqual のメソッドが認識できるように Microsoft の単体テスト フレームワークを使用します。
テスト メソッドの要件
テスト メソッドは、次の条件を満たす必要があります:
メソッドは [TestMethod] の属性で装飾する必要があります。
このメソッドは void を返します。
メソッドはパラメーターを持つことはできません。
テストをビルドして実行します
テストをビルドおよび実行するには
[ビルド] メニューの [ソリューションのビルド] をクリックします。
エラーがない場合、UnitTestExplorer のウィンドウは [テストを実行しない] のグループで Debit_WithValidAmount_UpdatesBalance に一覧表示されます。成功したビルドは、メニューの [テスト] を選択した後に、テストのエクスプローラーが表示されない場合は、[ウィンドウ] を選択し、 [テスト エクスプローラー] を選択します。
テストを実行するには [すべて実行] を選択します。テストの実行中にウィンドウの上部にあるステータス バーをアニメーション化しています。テストの実行の最後に、バーはテストのいずれかが失敗したすべてのテスト メソッドが成功した場合は、赤色または緑色を切り替えます。
この場合、テストは失敗します。テスト メソッドは [失敗したテスト] に実行されます。必要です。ウィンドウの下部の詳細を表示するには、テストのエクスプローラーのメソッドを選択します。
コードを修正、テストを再実行します。
テスト結果を分析します。
テスト結果は失敗を示すメッセージが含まれています。AreEquals のメソッドに対して、実際に受け取ったか、が何が予想されるメッセージの表示 (Expected<XXX> (パラメーター) Actual<YYY> (パラメーター)。まず、から低下する残高が調整が、代わりにコールバックの量乗算されたことが必要です。
再検査は、コードの単体テストがバグを検索に成功したことを示します。コールバックの量は、バランスに付けてする必要があるに追加されます。
バグを修正します。
エラーを修正するには、行を単純に置き換えます。
m_balance += amount;
with
m_balance -= amount;
テストを再実行します。
テストのエクスプローラーで、テストを再実行するには [すべて実行] を選択します。赤色または緑色の棒は緑色の回転、テストは [成功したテスト] のグループに移動されます。
コードを改善するために単体テストを使用します。
このセクションでは、分析、単体テストの開発とリファクタリングの反復処理の実行コードをよりも信頼性が高く、および有効にするために役立つかについて説明します。
問題を解析します。
テスト メソッドを作成したら、クラスに、元の分析の残りのケースに有効な量が Debit のメソッドで正しく推論されることを確認するために回って可能性があります:
メソッドは掛売金額がバランスを超える場合 ArgumentOutOfRangeException をスローします。
また、掛売金額がゼロより小さい場合 ArgumentOutOfRangeException をスローします。
テスト メソッドを作成します。
これらの問題を解決するために、テスト メソッドの作成の最初には似ています:ピックアップ
//unit test method
[TestMethod]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void Debit_WhenAmountIsLessThanZero_ShouldThrowArgumentOutOfRange()
{
// arrange
double beginningBalance = 11.99;
double debitAmount = -100.00;
BankAccount account = new BankAccount("Mr. Bryan Walton", beginningBalance);
// act
account.Debit(debitAmount);
// assert is handled by ExpectedException
}
また、右の例外がスローされたことを保持するために ExpectedExceptionAttribute の属性を使用します。ArgumentOutOfRangeException がスローされていない属性により、テストは失敗します。次に、量とテスト対象の正と負の debitAmount の値と、未満の一般的な ApplicationException をスローしないようにメソッドを変更することでテストを実行すると、テストが正しく動作することを示します。バックトラッキング数量がバランスを上回ったときに、ケースをテストするには、最初にする必要があるすべての長所:
Debit_WhenAmountIsMoreThanBalance_ShouldThrowArgumentOutOfRangeという名前の新しいテスト メソッドを作成します。
Debit_WhenAmountIsLessThanZero_ShouldThrowArgumentOutOfRange から新しいメソッドにメソッド本体をコピーします。
数に debitAmount バランスを大きく設定します。
テストを実行します。
debitAmount の値が異なる 2 種類のメソッドを実行すると、テストが完全に、残りのケースを処理することを示します。さらに、元の分析のすべてのケースが正しく処理されること、3 個のテストをすべて実行確認します。
分析を継続します
ただし、最後の 2 回のテスト メソッドでは、少し悩んでいます。テストの対象コードの場合、いずれかのテストの実行で調整する必要はあるがはっきりしていません。2 種類の要件を区別する方法が便利です。これは問題についても考慮するように、テストの中のほとんどを向上させたりどの要件が違反したかがわかっていることを明確になります。この情報は、ほとんどの下のテスト メソッドによってスローされると、例外を処理する運用機構に便利です。メソッドからスローするすべての関連するヘルプを表示するときに詳細情報の生成、ExpectedException の属性はこの情報を指定できません。
メソッドをテスト対象のもう一度参照、パラメーターとして渡される引数の取得名前と、条件付きステートメントが両方とも ArgumentOutOfRangeException のコンストラクターを使用するが表示されます:
throw new ArgumentOutOfRangeException("amount");
MSDN ライブラリの検索から、コンストラクターが、レポートの豊富な情報が存在していることを検出します。ArgumentOutOfRangeException(String, Object, String) は、引数、引数の値とユーザー定義メッセージの名前が含まれています。また、テスト対象のメソッドをリファクタリングし、このコンストラクターを使用できます。より、エラーを指定するのが一般に公開されている型のメンバーを使用できます。
テスト対象コードのリファクタリング
これは、クラス スコープで最初にエラー メッセージの 2 種類の定数を定義します:
// class under test
public const string DebitAmountExceedsBalanceMessage = "Debit amount exceeds balance";
public const string DebitAmountLessThanZeroMessage = "Debit amount less than zero";
これは、Debit のメソッドの 2 種類の条件付きステートメントが変更されます:
// method under test
// ...
if (amount > m_balance)
{
throw new ArgumentOutOfRangeException("amount", amount, DebitAmountExceedsBalanceMessage);
}
if (amount < 0)
{
throw new ArgumentOutOfRangeException("amount", amount, DebitAmountLessThanZeroMessage);
}
// ...
リファクタリング テスト メソッド
さらに、テスト メソッドでは、最初に ExpectedException の属性を削除します。代わりに、スローされた例外をキャッチし、正しい条件ステートメントでスローされたことを確認します。ただし、残りの条件を検証するには、2 種類の選択時に、ようにする必要があります。たとえば Debit_WhenAmountIsMoreThanBalance_ShouldThrowArgumentOutOfRange のメソッドでは次の操作のいずれかを 1 にとって可能性があります:
例外 (ArgumentOutOfRangeException のコンストラクターの 2 番目のパラメーター) の ActualValue のプロパティが先頭のバランスを超えることを保持します。このオプションは ActualValue がゼロより大きいことを意図したテスト メソッドの beginningBalance の変数に対して例外の ActualValue のプロパティをテストし、またはを確認する必要があります。
メッセージ (コンストラクターの 3 番目のパラメーター) を BankAccount のクラスに定義されている DebitAmountExceedsBalanceMessage を含めることをアサートします。
Microsoft の単体テスト フレームワークの StringAssert.Contains のメソッドは、最初の要求される計算なしで 2 番目のオプションを確認することをおができます。
Debit_WhenAmountIsMoreThanBalance_ShouldThrowArgumentOutOfRange の変更の 2 番目の試行は次のように思えるかも知れません:
[TestMethod]
public void Debit_WhenAmountIsGreaterThanBalance_ShouldThrowArgumentOutOfRange()
{
// arrange
double beginningBalance = 11.99;
double debitAmount = 20.0;
BankAccount account = new BankAccount("Mr. Bryan Walton", beginningBalance);\
// act
try
{
account.Debit(debitAmount);
}
catch (ArgumentOutOfRangeException e)
{
// assert
StringAssert.Contains(e.Message, BankAccount. DebitAmountExceedsBalanceMessage);
}
}
再検査、書き換えるは、再分析する
これは異なる値を持つテスト メソッドを再テストする場合は、次の点に発生します:
これは debitAmount のバランスを超える使用して正しいエラーを探し、Contains はパスを保持します。したがって、例外は、テスト メソッド パスの無視されます。これは、動作です。
これは debitAmountを使用すると、アサートが不適切なエラー メッセージがを返すため失敗します。アサートは、最初にテスト コードのパスでメソッドの別の位置に ArgumentOutOfRange の一時的な例外を挿入すると失敗します。これは非常に便利です。
debitAmount の値が有効な場合 (残高がゼロ以上未満、つまり、例外はキャッチされませんので、永続化ではキャッチされません。テスト メソッドのパス。これは、例外がスローされない場合、がテスト メソッドに失敗するため、ふさわしいです。
3 番目のファクトは、テスト メソッドのバグです。問題を解決しようとするには、テスト メソッドの終了時に Fail を Assert 例外がスローされるケースを処理するようにします。
ただし、再テストが適切な例外がキャッチされた場合、テストが失敗したことを示します。catch ステートメントで例外をリセットし、メソッドは引き続き実行し、Assert 新しいに失敗します。新しい問題を解決するために、StringAssertの後に return のステートメントを追加します。これで、問題を修正されたことを確認するの再テスト。Debit_WhenAmountIsMoreThanBalance_ShouldThrowArgumentOutOfRange の中の最終バージョンは次のようになります:
[TestMethod]
public void Debit_WhenAmountIsGreaterThanBalance_ShouldThrowArgumentOutOfRange()
{
// arrange
double beginningBalance = 11.99;
double debitAmount = 20.0;
BankAccount account = new BankAccount("Mr. Bryan Walton", beginningBalance);\
// act
try
{
account.Debit(debitAmount);
}
catch (ArgumentOutOfRangeException e)
{
// assert
StringAssert.Contains(e.Message, BankAccount. DebitAmountExceedsBalanceMessage);
return;
}
Assert.Fail("No exception was thrown.")
}
この最後のセクションでは、が向上したことを、作業がよりも信頼性が高く、わかりやすい title なテスト メソッド、テストのコードを説明しました。テスト対象のクラスをプロジェクトのコードを改善するために、さらに重要な、追加の解析は、ルーティング。