0

値がブール値であるかどうかをテストする単純な IsBoolean(x) 関数の単体テストを作成しています。テストしたい16の異なる値があります。

単体テストを個別に分割して、次のようにまとめて実行しなければ、地獄に落ちたり、.NET プログラミング コミュニティから無慈悲にからかわれたりすることになります (どちらが悪いでしょうか?)。

    [TestMethod]
    public void IsBoolean_VariousValues_ReturnsCorrectly()
    {

        //These should all be considered Boolean values
        Assert.IsTrue(General.IsBoolean(true));
        Assert.IsTrue(General.IsBoolean(false));
        Assert.IsTrue(General.IsBoolean("true"));
        Assert.IsTrue(General.IsBoolean("false"));
        Assert.IsTrue(General.IsBoolean("tRuE"));
        Assert.IsTrue(General.IsBoolean("fAlSe")); 
        Assert.IsTrue(General.IsBoolean(1));
        Assert.IsTrue(General.IsBoolean(0));
        Assert.IsTrue(General.IsBoolean(-1));

        //These should all be considered NOT boolean values
        Assert.IsFalse(General.IsBoolean(null));
        Assert.IsFalse(General.IsBoolean(""));
        Assert.IsFalse(General.IsBoolean("asdf"));
        Assert.IsFalse(General.IsBoolean(DateTime.MaxValue));
        Assert.IsFalse(General.IsBoolean(2));
        Assert.IsFalse(General.IsBoolean(-2));
        Assert.IsFalse(General.IsBoolean(int.MaxValue));
    }

私が読み続けている「ベストプラクティス」では、次のことを行う必要があるため、これを尋ねます。

    [TestMethod]
    public void IsBoolean_TrueValue_ReturnsTrue()
    {
        //Arrange
        var value = true;

        //Act
        var returnValue = General.IsBoolean(value);

        //Assert
        Assert.IsTrue(returnValue);

    }

    [TestMethod]
    public void IsBoolean_FalseValue_ReturnsTrue()
    {
        //Arrange
        var value = false;

        //Act
        var returnValue = General.IsBoolean(value);

        //Assert
        Assert.IsTrue(returnValue);

    }

    //Fell asleep at this point

これに対してテストする50以上の関数と500以上の値については、時間の無駄のように思えます....しかし、それはベストプラクティスです!!!!!

-ブレンダン

4

5 に答える 5

3

私はそれについて心配しません。この種のことは重要ではありません。JB Rainsberger は彼のトークIntegration Tests are a Scamでこれについて簡単に話しました。彼は次のように言いました。 、そうでない場合」。IMO、これは問題のないカテゴリに分類されます。

ちなみに、nunit を使用する場合は、少し便利なTestCaseAttributeを使用できます。

[TestCase(true)]
[TestCase("tRuE")]
[TestCase(false)]
public void IsBoolean_ValidBoolRepresentations_ReturnsTrue(object candidate)
{
    Assert.That(BooleanService.IsBoolean(candidate), Is.True);
}

[TestCase("-3.14")]
[TestCase("something else")]
[TestCase(7)]
public void IsBoolean_InvalidBoolRepresentations_ReturnsFalse(object candidate)
{
    Assert.That(BooleanService.IsBoolean(candidate), Is.False);
}

編集:テストを少し異なる方法で記述しました。これにより、意図が少しよく伝わると思います。

于 2013-01-31T03:53:01.390 に答える
2

エラーをより簡単に特定するために、値を区切ることがベストプラクティスであることに同意します。絶対的なものとしてではなく、自分の常識を持ってガイドラインとして従う必要があると思います。単体テストでアサーション数を最小限に抑えたいと考えていますが、一般的に最も重要なことは、テストごとに 1 つの概念を保証することです。

あなたの特定のケースでは、関数の単純さを考えると、あなたが提供した1つの単体テストは問題ないと思います. 読みやすく、シンプルで、明確です。また、関数を徹底的にテストし、行のどこかで問題が発生した場合でも、ソースをすばやく特定してデバッグすることができます。

追加の注意として、優れた単体テストを維持するために、常に最新の状態に保ち、実際の製品コードと同じように注意して扱う必要があります。これは多くの点で最大の課題です。おそらく、テスト駆動開発を行う一番の理由は、既存のコードを壊すことを心配する必要がなくなるため、実際に長期的にはより速くプログラミングできるようになることです。

于 2013-01-31T03:58:55.517 に答える
0

テストする各値を個別の単体テストに分割することをお勧めします。各単体テストには、渡す値と期待される結果に合わせて具体的に名前を付ける必要があります。コードを変更してテストの 1 つだけを壊した場合、そのテストだけが失敗し、残りの 15 はパスします。これにより、1 つのユニット テストをデバッグしてどのアサートが失敗したかを調べることなく、何が壊れたかを即座に知ることができます。

お役に立てれば。

于 2013-01-31T03:41:42.603 に答える
0

それらを個々のテストに分割する理由を少し考えてみてください。さまざまな機能を分離し、テストが中断したときに問題が発生したすべてのことを正確に特定するためです。Boolean と Not Boolean の 2 つをテストしているように見えるので、コードが 2 つの異なるパスをたどる場合は 2 つのテストを検討してください。ただし、より大きなポイントは、どのテストも壊れていなければ、正確に特定できるエラーがないということです。

それらを実行し続け、後でこれらのテストのいずれかが失敗した場合は、それらを個別のテストにリファクタリングし、そのままにしておきます。

于 2013-02-01T02:41:13.563 に答える
0

「ベスト プラクティス」については、そのようなものがないためコメントできません。

Ayende Rahienが彼のブログで述べていることに同意します。

結局のところ、私はテスト自体が製品にとって価値があるとは考えていないという事実に要約されます。彼らの唯一の価値は、製品が大丈夫かどうかを教えてくれるバイナリ能力です。テストに多くの余分な時間を費やすと、真の価値のある出荷可能なソフトウェアを作成することができなくなります。

それらすべてを 1 つのテストに入れ、このテストが「どこか」で失敗した場合、どうしますか? テスト フレームワークは失敗した行を正確に教えてくれます。失敗した場合は、デバッガーでステップ実行します。すべてが 1 つの機能に組み込まれているため、必要な余分な労力はごくわずかです。

この特定のインスタンスで失敗したテストのサブセットを正確に知ることの追加の価値は小さく、作成および維持する必要のある膨大な量のコードによって影が薄くなります。

于 2013-01-31T03:53:42.733 に答える