回答:
私の頭の中で、テストコードのコーディングスタイルには3つの違いが考えられます。
テストメソッドの命名では、のパターンに従いますshouldDoSomethingWhenSomeConditionHolds
。
テスト内では、次の間隔パターンに従うのが一般的です。
@Test
shouldReturnAccountBalenceWhenGetBalenceIsCalled() {
// Some lines
// of setup code
// go here.
// The action being tested happens after a blank line.
// An assertion follows another blank line.
}
テストごとに1つのアサーションのみを要求する人もいますが、これは普遍的とはほど遠いものです。
DRY(Do n't Repeat Yourself)は、実稼働コードよりもテストコードでの考慮事項が少なくなっています。いくつかの繰り返しコードをsetUpメソッドまたはtestUtilsクラスに配置する必要がありますが、テストコードの繰り返しをゼロにしようとすると、密結合で柔軟性のないテストが発生し、リファクタリングが妨げられます。
Roy Osheroveは、テストの命名に次のパターンを推奨しています。
NameOfMethodUnderTest_StateUnderTest_ExpectedBehavior()
http://weblogs.asp.net/rosherove/archive/2005/04/03/TestNamingStandards.aspxを参照してください
NameOfMethodUnderTestStateUnderTestExpectedBehavior()
;)
主なことは、単体テストは基本的にミニ仕様であることを覚えておくことです。これは、読みやすさを常に重視する必要があることを意味します。
第一に、これは、名前がテスト対象および主張されているものを明確に伝えなければならないことを意味します。
第二に、それは時々忘れられますが、仕様として、彼らはまさにそれを行うべきであるということです-動作を指定します。つまり、単体テストにロジックを含めるべきではありません-または、テストするのではなく、プログラムの機能を繰り返すというtrapに陥る可能性があります。
テストにはセットアップが複雑なオブジェクトが含まれることがあるため、オブジェクトマザーやテストデータビルダーなどを使用して、このセットアップロジックをテストとは別にするように努める必要があります。
本のいくつかの推奨事項で締めくくります。
xUnitテストパターン:リファクタリングテストコード:すばらしい本です。少し乾燥していると言う人もいますが、そうは思いません。テストを編成するさまざまな方法と、それらを保守可能にする方法について詳しく説明します。NUnitなどのようなものを使用している場合に関連します。
ユニットテストの技術:.Netの例を使用:テストの記述と保守の要点に関する最高の本。本当に新しいにもかかわらず、AAA構文が単なる別の方法ではなくかなり標準になったため、モックセクションはすでに少し古くなっています。
テストに導かれたオブジェクト指向ソフトウェアの成長:この本は素晴らしいです!群を抜いて最高の単体テストの本であり、ユニットテストを設計プロセスの第一級市民として位置づける唯一の先進的な本です。パブリックベータ版のときにこれを読んでいて、それ以来推奨されていました。本書全体で使用されている実物のような優れた実例。ロイの本を最初に読むことをお勧めします。
単体テストにロジックを入れないでください。たとえば、addメソッドをテストしているとしましょう。次のようなものがあります。
void MyTest_SaysHello()
{
string name = "Bob";
string expected = string.Format("Hello, {0}", name);
IMyObjectType myObject = new MyObjectType();
string actual = myObject.SayHello(name);
Assert.AreEqual(expected, actual);
}
この特定のケースでは、テストと同じロジックを繰り返している可能性が高いため、本質的には「1 + 1 == 2」ではなく「1 + 1 == 1 + 1」をテストしています。 「実際の」テスト。したがって、テストコードの実際の外観は次のようになります。
void MyTest_SaysHello()
{
string expected = "Hello, Bob";
IMyObjectType myObject = new MyObjectType();
string actual = myObject.SayHello("Bob");
Assert.AreEqual(expected, actual);
}
長い説明的なメソッド名。 テストメソッドはコードから呼び出されることはありません(リフレクションを介してそれらを検出して呼び出す単体テストランナーによって呼び出されるため)、気が狂ってメソッド名が50〜80文字の長さであってもかまいません。特定の命名規則(キャメルケース、アンダースコア、「should」、「must」、「when」、「given」など)は、名前が3つの質問に答える限り、それほど重要ではありません。
テスト方法は短くする必要があります。
テストメソッドは、単純な線形構造を持つ必要があります。ifまたはloopコンストラクトはありません。
テストメソッドは、「arrange-act-assert」パターンに従う必要があります。
各テストは1つのことをテストする必要があります。これは通常、テストごとに1つのアサートを意味します。次のようなテスト{ Do A; Assert B; Assert C; }
は2つにリファクタリングする必要が{ Do A; Assert B; }
あります。{ Do A; Assert C; }
ランダムなデータや「DateTime.Now」などを避けます
すべてのテストフィクスチャメンバーがテストの終了時に元の状態に戻されるようにします(たとえば、分解を使用)
本番コードで無慈悲に重複を削除しても、テストフィクスチャでのコードの重複ははるかに小さな問題です。