27

誰かがAssert.Inconclusive()をどのように使用すべきか疑問に思っています。

テストの目的以外の理由でユニットテストが失敗しそうな場合に使用しています。

たとえば、intの配列の合計を計算するクラスのメソッドがあります。同じクラスに、要素の平均を計算するメソッドもあります。これは、sumを呼び出し、それを配列の長さで割ることによって実装されます。

Sum()の単体テストの作成は簡単です。ただし、Average()のテストを作成し、Sum()が失敗すると、Average()も失敗する可能性があります。

平均の失敗は、失敗した理由について明確ではありません。テストする必要がある以外の理由で失敗しました。そのため、Sum()が正しい結果を返すかどうかを確認します。そうでない場合は、Assert.Inconclusive()を返します。

これは良い習慣と見なされますか?Assert.Inconclusiveは何を目的としていますか?それとも、分離フレームワークを使用して前の例を解決する必要がありますか?

4

4 に答える 4

26

不確定テストは、結果を判断できないテストです。たとえば、ある種の外部リソース(たとえば、インターネット接続)を使用するテストがある場合はどうでしょうか。接続が現在利用できない場合、これは実際にはテストが失敗したことを意味するわけではありません。一方、実際に実行せずに、成功としてマークするだけではいけません。したがって、それを不確定としてマークすると、これはテストレポートで確認できます。

注:一般に、テストでこのような外部リソースを使用しないでください。テストが脆弱になる可能性があります。

まだ終了していないテストには、MbUnitのExplicit属性を使用します。

于 2009-08-02T18:10:23.997 に答える
16

VSを使用して単体テストを生成すると、生成されたテストメソッドにAssert.Inclusiveを取得しました。通常、アサーションを変更して、それらを操作するときに何か別のものにします。テスト結果のAssert.Inconclusiveの疑問符をマーカーとして使用して、まだ完了していないテストをすばやく教えてくれます。

まあ、それは私がそれを使う方法です。その名前から「決定的ではない」ということから、それが何を意味するのかを文書化する限り、あなたはあなたの非決定的な状態を示すために使うことができると思います。

ただし、Average()メソッドの説明から、ユニットテストは1つの「ユニット」、1つの特定のシナリオだけをカバーするのに十分なアトミックではないと思います。時々、私は単一のメソッドに対して2つまたは3つの単体テストメソッドを記述します。Average()または、メソッドを単一の責任をカバーするより小さなメソッドに分割することもできます。そうすれば、ユニットテストを行う前に、これらの小さなメソッドをユニットテストできますAverage()


ヨハネス、

これは私がSum()Average()メソッドを実装する方法です。

public static class MyMath
{
    private static void ValidateInput(ICollection<int> numbers)
    {
        if (numbers == null)
            throw new ArgumentNullException("numbers", "Null input.  Nothing to compute!");
        if (numbers.Count == 0)
            throw new ArgumentException("Input is empty.  Nothing to compute!");
    }

    public static int Sum(int[] numbers)
    {
        ValidateInput(numbers);

        var total = 0;
        foreach (var number in numbers)
            total += number;

        return total;
    }

    public static double Average(int[] numbers)
    {
        ValidateInput(numbers);
        return Sum(numbers) / numbers.Length;
    }
}

簡単にするために、メソッドArgumentExceptionから例外をスローするだけです。また、オーバーフローしてメソッドValidateInput(ICollection<int>)をスローする可能性を確認することもできます。OverflowExceptionValidateInput(ICollection<int>)

そうは言っても、これが私がAverage(int[])関数をテストする方法です。

[TestMethod]
public void AverageTest_GoodInput()
{
    int[] numbers = {1, 2, 3};
    const double expected = 2.0;
    var actual = MyMath.Average(numbers);
    Assert.AreEqual(expected, actual);
}

[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void AverageTest_NullInput()
{
    int[] numbers = null;
    MyMath.Average(numbers);
}

[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void AverageTest_EmptyInput()
{
    var numbers = new int[0];
    MyMath.Average(numbers);
}

これらのテストのセットアップにより、すべてのテストに合格したときに、私の機能が正しいことを確信できます。まあ、オーバーフローの場合を除いて。これで、メソッドに戻ってValidateInput(ICollection<int>)オーバーフローをチェックするロジックを追加してから、OverflowExceptionオーバーフローの原因となる種類の入力に対してがスローされることを期待するテストをもう1つ追加できます。または、TDDを使用してアプローチする場合は、逆の順序で実行します。

これがアイデアを明確にするのに役立つことを願っています。

于 2009-08-02T18:50:24.430 に答える
10

I only Assert.Inconclusive on unit tests I haven't written yet. Sometimes when writing something I realize some corner case that I don't want to miss. So I quickly jump over, write the test method with a descriptive name and add a single line of Assert.Inconclusive.

The reason for doing this is that it provides documentation on things that I need to test without interrupting my work flow too much. It also makes it possible to filter out test failures quickly in the result list. Having an inconclusive failure means I haven't broken anything I just more tests to write.

于 2009-08-02T17:06:35.693 に答える
8

Assert.Inconclusiveは、次のいずれかを示します。

私はまだテストを書いていません;私はテストメソッドを作成しただけです

-また-

私のテストには依存関係があり、その依存関係は利用できません。例えば

List<Customer> custs = o.GetAllCustomers();
if (custs.Count == 0)
{
  Assert.Inconclusive("No customers to test");
  return;
}
于 2010-05-04T19:45:02.003 に答える