74

私は TDD を行うときに Assert.Fail をよく使用します。私は通常、一度に 1 つのテストに取り組んでいますが、後で実装したいもののアイデアが浮かんだら、すぐに空のテストを作成します。テスト メソッドの名前は、実装したいものを一種の todo リストとして示します。忘れないように、本体に Assert.Fail() を入れました。

xUnit.Net を試してみると、Assert.Fail が実装されていないことがわかりました。もちろん、いつでも Assert.IsTrue(false) を実行できますが、これも私の意図を伝えません。Assert.Fail は意図的に実装されていない印象を受けました。これは悪い習慣と見なされますか? もしそうなら、なぜですか?


@Martin Meredithそれはまさに私がしていることではありません。最初にテストを書いてから、それを機能させるコードを実装します。通常、一度にいくつかのテストを考えます。または、何か他の作業をしているときに書くテストについて考えます。そのとき、覚えておくために空の失敗したテストを書きます。テストを書き始める頃には、きちんとテストファーストで作業しています。

@Jimmehそれは良い考えのようです。無視されたテストは失敗しませんが、別のリストに表示されます。それを試してみる必要があります。

@Matt Howells 素晴らしいアイデア。この場合、NotImplementedException は assert.Fail() よりも意図をよく伝えます

@Mitch Wheatそれが私が探していたものです。別の方法で悪用されるのを防ぐために除外されたようです。

4

14 に答える 14

54

このシナリオでは、Assert.Fail を呼び出すのではなく、次のことを行います (C# / NUnit で)

[Test]
public void MyClassDoesSomething()
{
    throw new NotImplementedException();
}

Assert.Fail よりも明示的です。

Assert.Fail() よりも明示的なアサーションを使用する方が望ましいという一般的な合意があるようです。ただし、ほとんどのフレームワークは、より良い代替手段を提供していないため、それを含める必要があります. たとえば、NUnit (およびその他) は、ExpectedExceptionAttribute を提供して、一部のコードが特定のクラスの例外をスローすることをテストします。ただし、例外のプロパティが特定の値に設定されていることをテストするために、それを使用することはできません。代わりに、Assert.Fail に頼る必要があります。

[Test]
public void ThrowsExceptionCorrectly()
{
    const string BAD_INPUT = "bad input";
    try
    {
        new MyClass().DoSomething(BAD_INPUT);
        Assert.Fail("No exception was thrown");
    }
    catch (MyCustomException ex)
    {
         Assert.AreEqual(BAD_INPUT, ex.InputString); 
    }
}

xUnit.Net メソッドの Assert.Throws を使用すると、Assert.Fail メソッドを必要とせずに、これをより簡単に行うことができます。Assert.Fail() メソッドを含めないことで、xUnit.Net は、開発者がより明示的な代替手段を見つけて使用し、必要に応じて新しいアサーションの作成をサポートすることを奨励します。

于 2008-09-23T12:32:30.690 に答える
17

それは意図的に取り残されました。これは、Assert.Fail() がない理由に関する Brad Wilson の回答です。

実際、私たちはこれを見落としませんでした。Assert.Fail は松葉杖であり、おそらくアサーションが欠落していることを意味します。テストが構造化されているだけの場合もあれば、Assert が別のアサーションを使用できるためである場合もあります。

于 2008-09-23T12:32:17.493 に答える
11

私は常に Assert.Fail() を使用して、単純な値の比較を超えたロジックによってテストが失敗する必要があることを検出したケースを処理しました。例として:

try 
{
  // Some code that should throw ExceptionX
  Assert.Fail("ExceptionX should be thrown")
} 
catch ( ExceptionX ex ) 
{
  // test passed
}

したがって、フレームワークに Assert.Fail() がないことは、私には間違いのように見えます。Assert クラスにパッチを適用して Fail() メソッドを含め、それを追加する理由とともにフレームワーク開発者にパッチを提出することをお勧めします。

ワークスペースで意図的に失敗するテストを作成するというあなたの習慣については、コミットする前にそれらを実装することを忘れないでください。それは私にとっては良い習慣のようです.

于 2008-09-23T12:41:53.273 に答える
5

単体テストには MbUnit を使用しています。テスト スイートでは (緑や赤ではなく) オレンジ色で表示されるテストを無視するオプションがあります。おそらく xUnit にも似たようなものがありますが、メソッドに assert を入れる必要さえないということでしょうか?

編集:

MbUnit では、次のようになります。

[Test]
[Ignore]
public void YourTest()
{ } 
于 2008-09-23T12:30:57.853 に答える
4

これは、設計上例外をスローするコードのテストを作成するときに使用するパターンです。

[TestMethod]
public void TestForException()
{
    Exception _Exception = null;

    try
    {
        //Code that I expect to throw the exception.
        MyClass _MyClass = null;
        _MyClass.SomeMethod();
        //Code that I expect to throw the exception.
    }
    catch(Exception _ThrownException)
    {   
        _Exception = _ThrownException
    }
    finally
    {
        Assert.IsNotNull(_Exception);
        //Replace NullReferenceException with expected exception.
        Assert.IsInstanceOfType(_Exception, typeof(NullReferenceException));
    }
}

IMHO これは、Assert.Fail() を使用するよりも例外をテストするためのより良い方法です。その理由は、スローされる例外をテストするだけでなく、例外の種類もテストするためです。これは Matt Howells からの回答に似ていますが、finally ブロックを使用した IMHO の方が堅牢です。

もちろん、例外の入力文字列などをテストするために、他の Assert メソッドを含めることも可能です。私のパターンに関するコメントや意見をいただければ幸いです。

于 2009-06-26T11:28:12.663 に答える
3

個人的には、このようにテスト スイートを todo リストとして使用しても問題はありませんが、合格するコードを実装する 前に最終的にテストを作成することができれば問題ありません。

そうは言っても、私はこのアプローチを自分で使用していましたが、今ではそうすると、前もって多くのテストを作成する道にたどり着くことがわかりました。これは、奇妙な方法で、テストをまったく作成しないという逆の問題のようなものです。デザインに関する決定を下すのは、私見では少し早すぎます。

ちなみに、MSTest では、標準の Test テンプレートはサンプルの最後で Assert.Inconclusive を使用します。

私の知る限り、xUnit.NETフレームワークは非常に軽量であることを意図しており、開発者が明示的な失敗条件を使用することを奨励するために、Failを意図的にカットしました。

于 2008-09-23T12:38:31.657 に答える
2

大雑把な推測: Assert.Fail を保留するのは、テスト コードを記述する良い方法は、悪いケースで Assert.Fail につながるスパゲッティの巨大な山であると考えないようにするためです。[追加する編集:他の人の回答はこれを広く確認していますが、引用があります]

それはあなたがしていることではないので、xUnit.Net が過保護になっている可能性があります。

あるいは、彼らはそれが非常にまれであり、非直交的であるため不要であると考えているだけかもしれません.

私は ThisCodeHasNotBeenWrittenYet という関数を実装することを好みます (実際には、入力しやすいようにもっと短い関数です)。それ以上に明確に意図を伝えることはできず、正確な検索用語があります。

それが失敗するか、実装されていない (リンカ エラーを引き起こす) か、またはコンパイルされないマクロであるかは、現在の好みに合わせて変更できます。たとえば、完了したものを実行したい場合、失敗が必要です。それらすべてを取り除くために座っているときは、コンパイルエラーが必要になる場合があります。

于 2008-09-23T12:45:26.570 に答える
2

私が通常行う良いコードでは:

void goodCode() {
     // TODO void goodCode()
     throw new NotSupportedOperationException("void goodCode()");
}

私が通常行うテストコードでは:

@Test
void testSomething() {
     // TODO void test Something
     Assert.assert("Some descriptive text about what to test")
}

JUnitを使用していて、失敗したくないがエラーが発生したくない場合は、通常、次のようにします。

@Test
void testSomething() {
     // TODO void test Something
     throw new NotSupportedOperationException("Some descriptive text about what to test")
}
于 2008-09-23T14:01:00.790 に答える
1

Assert.Fail開発者がばかげた、または壊れたテストを作成するようになるため、その破壊的な影響に注意してください。例えば:

[TestMethod]
public void TestWork()
{
    try {
        Work();
    }
    catch {
        Assert.Fail();
    }
}

try-catch は冗長なので、これはばかげています。例外がスローされると、テストは失敗します。

また

[TestMethod]
public void TestDivide()
{
    try {
        Divide(5,0);
        Assert.Fail();
    } catch { }
}

これは壊れており、Divide 関数の結果が何であれ、テストは常にパスします。繰り返しますが、テストは、例外がスローされた場合にのみ失敗します。

于 2014-08-28T10:49:54.840 に答える
0

Assert.Fail例外をスローする必要があると言うのになぜ使用するのですか? それは不要です。ExpectedException属性を使用しないのはなぜですか?

于 2008-10-25T02:53:56.553 に答える
0

失敗するだけのテストを書いていて、そのためのコードを書いている場合は、テストを書いています。これはテスト駆動開発ではありません。

技術的には、テスト駆動開発を正しく使用している場合、Assert.fail() は必要ありません。

Todo リストを使用したり、GTD 方法論を仕事に適用したりすることを考えたことはありますか?

于 2008-09-23T12:31:09.883 に答える
0

MS Test にはAssert.Fail()がありますが、Assert.Inconclusive()もあります。Assert.Fail() の最も適切な使用法は、アサーションに入れるのが面倒なインライン ロジックがある場合だと思いますが、良い例は思いつきません。ほとんどの場合、テスト フレームワークが Assert.Fail() 以外のものをサポートしている場合は、それを使用します。

于 2008-09-23T12:36:58.637 に答える