3

各テストは 1 つのことだけをテストする必要があるとどこかで読みました。しかし、同様の行動をグループ化することは、グッド プラクティス ハンドブックで許可されていますか? 私は現在いくつかのテスト(NUnitを使用したC#)を書いていますが、以下は私が直面しているものの例です:

[TearDown]
public void Cleanup()
{
    Hotkeys.UnregisterAllLocals();
    Hotkeys.UnregisterAllGlobals();
}

[Test]
public void KeyOrderDoesNotMatter()
{
    Hotkeys.RegisterGlobal("Ctrl+Alt+P", delegate { });
    Assert.That(Hotkeys.IsRegisteredGlobal("Alt+P+Ctrl"), Is.True);
}

[Test]
public void KeyCaseDoesNotMatter()
{
    Hotkeys.RegisterGlobal("Ctrl+Alt+P", delegate { });
    Assert.That(Hotkeys.IsRegisteredGlobal("ctrl+alt+p"), Is.True);
}

[Test]
public void KeySpacesDoesNotMatter()
{
    Hotkeys.RegisterGlobal("Ctrl+Alt+P", delegate { });
    Assert.That(Hotkeys.IsRegisteredGlobal("Ctrl + Alt + P"), Is.True);
}

グループ化すると、次のようになります。

[TearDown]
public void Cleanup()
{
    Hotkeys.UnregisterAllLocals();
    Hotkeys.UnregisterAllGlobals();
}

[Test]
public void KeyIsNotStrict()
{
    // order
    Hotkeys.RegisterGlobal("Ctrl+Alt+A", delegate { });
    Assert.That(Hotkeys.IsRegisteredGlobal("Alt+A+Ctrl"), Is.True);

    // whitespace
    Hotkeys.RegisterGlobal("Ctrl+Alt+B", delegate { });
    Assert.That(Hotkeys.IsRegisteredGlobal("Ctrl + Alt + B"), Is.True);

    // case
    Hotkeys.RegisterGlobal("Ctrl+Alt+C", delegate { });
    Assert.That(Hotkeys.IsRegisteredGlobal("ctrl+alt+c"), Is.True);
}

では、ベスト プラクティス (存在する場合) とその理由は何ですか?

obs: 私は単体テストに比較的慣れていません...

4

2 に答える 2

6

短い答えはノーです。テストはできるだけ単純にする必要があります。各テストは、1 つのことだけをテストする必要があります。

単体テスト用のArrange-Act-Assert (AAA)パターンがあります。これは、テストメソッドの最初にいくつかの準備を行い(Arrange)、次にこのテストがチェックするアクションを実行し、メソッドの最後にいくつかのアサーションを行う必要があることを示しています。

また、単体テスト用のFIRSTパターンについて読むことをお勧めします。

更新:

テストを複雑にすると、テストが「赤」になったときに何が問題なのかを認識するのが難しくなります。いくつかのアサートが失敗したことがわかりますが、どのアサートを理解するためにログを読む必要があります。さらに、複雑なテストの最初のアサートが失敗した場合、残りのアサートが OK かどうかさえわかりません。大規模な単体テストを維持することも困難です。最初のアサーションに対して行った作業には、次のアサーションに影響を与える副作用がある場合があります。

ただし、GRASPに関するテストも低結合/高凝集性でなければならないことを考慮する必要があります。そのため、@Schwern が彼の回答で述べたように、別のテストが終了する場合にアサーションを最小限に抑えるためだけに個別のテストを作成しないでください。同じ論理的なことをテストします。それぞれの特定のケースでどちらの方法が正しいかを決定するのは、常に開発者の裁量です。

于 2013-01-13T20:01:42.317 に答える
5

注: 私は C# プログラマーではありません。

一方では、「テストで 1 つのことだけを行う」必要があります。もう一方には、DRY Principleがあります。どちらに違反するかを尋ねられます。これは、それぞれのルールにどれだけ違反しているか、違反からどれだけの利益が得られるか、そもそもこれらのルールが存在する理由によって異なります。

グループ化されたソリューションは、まだ繰り返されるため、理想的ではありません。代わりにこれをした場合...

[TearDown]
public void Cleanup()
{
    Hotkeys.UnregisterAllLocals();
    Hotkeys.UnregisterAllGlobals();
}

[Test]
public void IsRegisteredGlobal_InputNormalization()
{
    Hotkeys.RegisterGlobal("Ctrl+Alt+P", delegate { });

    Assert.IsTrue(Hotkeys.IsRegisteredGlobal("Alt+P+Ctrl"),     "order independent");
    Assert.IsTrue(Hotkeys.IsRegisteredGlobal("ctrl+alt+p"),     "case insensitive");
    Assert.IsTrue(Hotkeys.IsRegisteredGlobal("Ctrl + Alt + P"), "whitespace independent");
}

そうすれば、DRY に違反することはなく、「テストで 1 つのことだけを行う」ということもほとんどありません。まだ 1 つの「こと」を行っており、そのことは IsRegisteredGlobal の入力を正規化しています。

それらを分離するために、テストごとに 1 つのことだけを行います。これにより、テストの分離とデバッグが容易になります。これは、テストごとに 1つのアサートを意味するものではありません。上記のテストはまだ 1 つのことしか行っていませんが、非常によく似た 3 つの方法でテストしています。これで結構です。以前は、アサートはテスト名で説明されていました。現在は、各アサートに関連付けられたメッセージによって説明されています。失敗の理由は明らかで、FIRST の I です。

さらに、メソッドごとに 1 つの assert を使用してすべてのテストを記述し、同じコードを不必要に何度も繰り返すと、DRY に違反するだけでなく、繰り返されるコードによって速度が低下し、FIRST の F に違反する可能性があります。

順序を逆にすると true にならないのに、checkingによって true になるHotkeys.IsRegisteredGlobal("Alt+P+Ctrl")可能性はありますか? Hotkeys.IsRegisteredGlobal("ctrl+alt+p")はい。しかし、分離、速度、利便性の間には常にトレードオフがあります。一方が他方に干渉する可能性があると思われる場合は、それらを分離する必要があります。間に結合がないことを確認したい場合は、すべてのテストにその負担をかけるのではなく、独自のテストで明示的に行う必要があります。

はい、コードを実行して複数のアサートを行うことは問題ありませんが、それは優れたコードと優れたテストの間のバランスをとる行為であることを常に覚えておいてください。通常、テストは成功しますが、ばかげてはいけません。

コンパクトさ、明快さ、および潜在的に優れた障害診断のために IsTrue、ジェネリックではなく切り替えました。最後まで何をテストしているのかわからないことを意味します。行全体を読んで状態を確認し、実際にテストしているものに照らして行全体をもう一度読む必要があります。 前もって言います。 複雑なアサーションでは読みやすいかもしれませんが、単純なアサーションでは読みにくくなります。用途に合わせて使えばOKです。(注: Perl プログラマー)ThatAssert.That( thing, condition )Assert.IsTrueAssert.That

また、意図に関するより多くの情報を NUnit に提供しているため、より優れた障害診断を生成できる可能性もあります。「これはそれと一致する」ではなく「これは真である」ので、より正確で巧妙なアサートを生成できます。ただし、NUnit は、テストしていることを確認Is.Trueし、とにかくそれを実行するのに十分なほど賢いかもしれません。痛くない。

于 2013-01-13T20:13:29.667 に答える