11
votes

Meilleures pratiques pour de multiples affirmations sur le même résultat en C #

Que pensez-vous que la meilleure façon de faire de multiples asserts sur un résultat? Dans le passé, j'ai mis tout le même test, mais cela commence à me sentir un peu sale, je viens de jouer avec une autre idée à l'aide de la configuration.

[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));
    }
}


0 commentaires

4 Réponses :


3
votes

Ce dont vous avez besoin pour garder est le modèle de organiser, affirmer (et puis terminez le test). Dans votre cas, tout l'arrangement est dans le TestFixTureSetup , tout comme l'action testée. Je vais réorganiser cela un peu, il peut devenir lourd lorsque vous avez plus de tests. Comme les notes de Dockers, il convient d'éviter des problèmes de test lourds, ils peuvent devenir des problèmes - ils sont "une taille unique pour tous" sur tous les tests de la classe et peuvent donc devenir plus lourds que la plupart des tests ont besoin.

Si vous êtes tenté de continuer à poursuivre une autre action de suivi, puis davantage d'affirmation, mettez ceci dans un test séparé.

Je n'ai aucun problème à mettre plusieurs asserts dans le même test, tant qu'ils contribuent à tester la même chose (c'est une partie de la même "affirmation logique"). Dans ce cas, tout nombre d'affirmations sur le contenu de cela.Result.data serait correct par moi - ils inspecteraient tous la même valeur de résultat. Votre get_uceStaticsettings_hasdata Est-ce très clairement. Il est préférable d'utiliser un message d'échec unique sur chaque affirmation afin qu'il soit plus facile de dire quelle affirmation a échoué.

alternativement, vous pourriez envelopper les affirmations connexes dans une seule méthode. Ceci est utile pour les raisons secs habituelles si vous l'utilisez plus d'une fois, mais sinon je ne vois pas que c'est une grande différence.

en résumé de
* Faire une action par test
* Après l'action, utilisez autant d'affirmations connexes que vous devez tester une chose de
* Terminez le test là-bas.


0 commentaires

15
votes

avoir plusieurs assertions dans le même test peut conduire à assertion roulette , donc c'est quelque chose de que vous devriez toujours faire attention.

Toutefois, la roulette Assertion est principalement un problème lorsque les affirmations sont non liées . S'ils sont conceptuels étroitement liés, de nombreuses assertions peuvent souvent être considérées comme un seul affirmations logiques .

Dans de nombreux cas, vous pouvez obtenir le meilleur des deux mondes en encapsulant explicitement une assertion aussi logique dans un type ou une méthode personnalisée.


3 commentaires

"Assertions logiques" est un bon mot pour cela. Il est intéressant de noter que l'exemple d'assertion de la roulette est essentiellement un exemple de "Comment passer mal en ne faisant pas d'arrangement-act-agir". Les concepts diffèrent-ils?


@Anthony: Les concepts diffèrent, bien qu'ils soient étroitement liés. Vous êtes beaucoup moins susceptible de ressentir la douleur de l'assertion Roulette si vous suivez AAA (ou un test de quatre phases lorsque les modèles de test Xunit l'appelle), mais je serais toujours varié d'avoir des affirmations entièrement non liées dans le même bloc d'affirmation.


L'idée d'assertion Roulette peut être minimisée dans Nunit en spécifiant un commentaire dans la déclaration d'assertion. Au lieu de faire "affirmer.That (condition)" "Utilisez" assert.That (condition, écheceuremessage) "où" écheceffessage "est une information sur ce que l'affirmation vérifiait. Cela vous permettra de savoir exactement qui affirmer dans un test unitaire a échoué.



2
votes

Vous pouvez utiliser OAPT - une addition de renseignements sur la renonciation à l'exécution d'une revendication par test:

[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)));
  }
}


0 commentaires

0
votes

J'ai tendance à mettre des affirmations seules seules s'ils sont précieux seuls. Si je veux une affirmation à elle seule, je fais une affirmation personnalisée: xxx pré>

Parfois, je tiens à avoir plus d'un exemple dans un test. Je fais cela lorsque la moitié du comportement n'a aucune valeur sans l'autre moitié. P>

Assert.True(list.IsEmpty());

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


0 commentaires