11

結果に対して複数のアサートを行う最もクリーンな方法は何だと思いますか? 過去に私はそれらをすべて同じようにテストしましたが、これは少し汚れているように感じ始めています.セットアップを使用して別のアイデアで遊んでいます.

[TestFixture]
public class GridControllerTests
{
    protected readonly string RequestedViewId = "A1";

    protected GridViewModel Result { get; set;}

    [TestFixtureSetUp]
    public void Get_UsingStaticSettings_Assign()
    {
        var dataRepository = new XmlRepository("test.xml");

        var settingsRepository = new StaticViewSettingsRepository();

        var controller = new GridController(dataRepository, settingsRepository);

        this.Result = controller.Get(RequestedViewId);

    }

    [Test]
    public void Get_UsingStaticSettings_NotNull()
    {
        Assert.That(this.Result,Is.Not.Null);
    }

    [Test]
    public void Get_UsingStaticSettings_HasData()
    {
        Assert.That(this.Result.Data,Is.Not.Null);
        Assert.That(this.Result.Data.Count,Is.GreaterThan(0));
    }

    [Test]
    public void Get_UsingStaticSettings_IdMatches()
    {
        Assert.That(this.Result.State.ViewId,Is.EqualTo(RequestedViewId));
    }

    [Test]
    public void Get_UsingStaticSettings_FirstTimePageIsOne()
    {
        Assert.That(this.Result.State.CurrentPage, Is.EqualTo(1));
    }
}
4

4 に答える 4

15

同じテストに複数のアサーションがあると、アサーション ルーレットが発生する可能性があるため、これには常に注意する必要があります。

ただし、Assertion Roulette は主に、アサーションが無関係な場合に問題になります。それらが概念的に密接に関連している場合、多くのアサーションはしばしば単一の論理アサーションと見なすことができます。

多くの場合、このような論理アサーションをカスタム タイプまたはメソッドに明示的にカプセル化することで、両方の長所を活かすことができます。

于 2010-01-14T09:47:33.070 に答える
3

守る必要があるのは、Arrange、Act、Assert (そしてテストを終了する) のパターンです。あなたの場合、TestFixtureSetUpテストされているアクションと同様に、すべての配置は にあります。これを少し整理し直します。テストが増えると扱いにくくなる可能性があります。Dockersが指摘しているように、重いテスト設定は避けるべきであり、問​​題になる可能性があります.クラスのすべてのテストで「フリーサイズ」であるため、ほとんどのテストが必要とするよりも重くなる可能性があります.

別の後続のアクションに進み、さらにアサートしたい場合は、これを別のテストに入れます。

複数のアサーションを同じテストに入れることに問題はありませんが、それらが同じもののテストに貢献する限り (つまり、同じ「論理アサーション」の一部である場合)。この場合、 this.Result.Data のコンテンツに対するアサートの数に制限はありません。それらはすべて同じ結果値を検査します。あなたGet_UsingStaticSettings_HasDataはこれを非常に明確に行います。どのアサートが失敗したかを簡単に判断できるように、各アサートで一意の失敗メッセージを使用することをお勧めします。

または、関連するアサートを 1 つのメソッドにまとめることもできます。これは、複数回使用する場合、通常の DRY の理由で役立ちますが、それ以外の場合、大きな違いはないと思います。

要約
* テストごとに 1 つのアクションを実行する
* アクションの後、1 つのことをテストするために必要な数の関連するアサートを使用する
* そこでテストを終了する。

于 2010-01-14T09:43:19.083 に答える
2

Oapt - テストごとに 1 つのアサートを実行するための NUnit アドインを使用できます。

[TestFixture]
public class GridControllerTests
{
  [TestCase, ForEachAssert]
  public void Get_UsingStaticSettings_Assign()
  {
      var dataRepository = new XmlRepository("test.xml");
      var settingsRepository = new StaticViewSettingsRepository();
      var controller = new GridController(dataRepository, settingsRepository);

      var result = controller.Get("A1");

      AssertOne.From(
        () => Assert.That(this.Result,Is.Not.Null),
        () => Assert.That(this.Result.Data,Is.Not.Null),
        () => Assert.That(this.Result.Data.Count,Is.GreaterThan(0)),
        () => Assert.That(this.Result.State.ViewId,Is.EqualTo(RequestedViewId)),
        () => Assert.That(this.Result.State.CurrentPage, Is.EqualTo(1)));
  }
}

これにより、アサートごとに 1 つずつ、5 つの異なるテスト ケースが作成されます。

于 2010-05-29T13:00:36.317 に答える
0

私は、それ自体に価値がある場合にのみ、アサーションを独自のものにする傾向があります。独自のアサーションが必要な場合は、カスタム アサーションを作成します。

AssertThatMyObjectMatches(field1, field2, field3, field4, myObject);

ただし、テストで複数の例を使用したい場合もあります。私がこれを行うのは、行動の半分が残りの半分なしでは価値がない場合です。

Assert.True(list.IsEmpty());

list.Add(new Thing());
Assert.False(list.IsEmpty());

Ruby コミュニティの多くを含む他の人々は、これについて異なる意見を持っています。これは主に、Dave Astels のブログ投稿によって推進されています。

http://www.artima.com/weblogs/viewpost.jsp?thread=35578

「テストごとに 1 つのアサーション」方式は、検証など、小さな側面のそれぞれが価値のあるものに非常に役立つと思います。そうでなければ、私はそれについてあまり心配していません。

あなたとあなたのチームにとってうまくいくものは、おそらく正しい方法です。私は、単純で簡単に変更できると思われることは何でも、後になって正しいことをよりよく理解したときに、正しいことを実行する傾向があります。また、より複雑な例にはユニットレベルのGiven / When / Thenコメントをたくさん入れ、複雑すぎて理解できない場合はクラスを分割します。

このようにテストを書く理由は、壊れるものをキャッチできるようにするためではありません。それは、人々がコードを理解し、そもそも物事を壊すことなくコードを変更できるようにするためです。

于 2010-06-23T19:29:39.533 に答える