Différences entre Given When Then (GWT) et Arrange Act Assert (AAA)?

13

Dans TDD, il existe une syntaxe Arrange Act Assert (AAA):

[Test]
public void Test_ReturnItemForRefund_ReturnsStockOfBlackSweatersAsTwo_WhenOneInStockAndOneIsReturned()
{
    //Arrange
    ShopStock shopStock = new ShopStock();
    Item blackSweater = new Item("ID: 25");
    shopStock.AddStock(blackSweater);
    int expectedResult = 2;
    Item blackSweaterToReturn = new Item("ID: 25");

    //Act
    shopStock.ReturnItemForRefund(blackSweaterToReturn);
    int actualResult = shopStock.GetStock("ID: 25");

    //Assert
    Assert.AreEqual(expectedResult, actualResult);
}

Dans BDD, les tests d'écriture utilisent une structure similaire mais avec la syntaxe Given When Then (GWT):

    [Given(@"a customer previously bought a black sweater from me")]
    public void GivenACustomerPreviouslyBoughtABlackSweaterFromMe()
    { /* Code goes here */   }

    [Given(@"I currently have three black sweaters left in stock")]
    public void GivenICurrentlyHaveThreeBlackSweatersLeftInStock()
    { /* Code goes here */   }

    [When(@"he returns the sweater for a refund")]
    public void WhenHeReturnsTheSweaterForARefund()
    { /* Code goes here */   }

    [Then(@"I should have four black sweaters in stock")]
    public void ThenIShouldHaveFourBlackSweatersInStock()
    { /* Code goes here */   }

Bien qu'ils soient souvent considérés comme identiques, il existe des différences. En voici quelques-uns:

  1. GWT peut être mappé directement à la spécification d'un fichier d'entités dans les cadres BDD

  2. GWT est plus facile à comprendre pour les non-développeurs en encourageant l'utilisation d'un anglais simple et en ayant une courte description de ce que fait chaque partie.

  3. Étant donné quand et alors sont des mots clés dans divers cadres BDD tels que SpecFlow et Cucumber

Ma question est la suivante: existe-t-il d'autres différences (outre les noms) entre AAA et GWT? Et y a-t-il une raison, outre celles spécifiées ci-dessus, que l'une devrait être préférée à l'autre?

Cognitive_chaos
la source
3
Je ne vois pas de différence, sauf pour les «se lit plus comme un langage naturel». Étant donné un arrangement, lorsqu'une action se produit, affirmez alors des choses sur le nouvel état.
Sjoerd Job Postmus
Je pense que vous avez trouvé quelques points pertinents et que vous ne recevrez probablement pas de réponse avec des différences supplémentaires. Pour ce que ça vaut, j'utilise exclusivement AAA pour les tests unitaires car le format est complètement indépendant de la méthodologie mais encourage les petits tests indépendants.
amon

Réponses:

9

Je pense que vous avez très bien énuméré les différences dans votre question, mais j'ajouterai certaines de mes opinions sur la façon dont je vois les deux approches.

AAA est très utile pour moi lorsque je teste mon propre code. Si je travaille sur un projet ou une bibliothèque pour moi, AAA est ma voie. Il me permet de configurer tout ce dont j'ai besoin pour exécuter mon test, puis de le tester . C'est rapide à configurer et rapide à vérifier que mon code fonctionne comme prévu.

GWT est utile dans les environnements d'entreprise, où le travail effectué par les programmeurs doit être mappé à la valeur métier. La valeur commerciale est mappée par des fonctionnalités et, espérons-le, des fonctionnalités qui n'introduisent pas de bogues. Il existe de nombreuses stratégies pour mapper les fonctionnalités aux tâches de programmation, mais l'une d'entre elles concerne les exigences. D'après mon expérience, les exigences vont des exigences au niveau de l'utilisateur jusqu'aux petites tâches à exécuter par l'utilisateur. Ceci est utile car il est facile pour les gestionnaires de comprendre comment le travail du programmeur a un impact sur leurs clients / utilisateurs, et donc pourquoi les programmeurs ajoutent de la valeur à leur entreprise

  • Exigence au niveau de l'utilisateur: étant donné que l'entrepôt a au moins N article (s) en stock, lorsqu'un utilisateur achète N article (s), l'entrepôt expédie N article (s) à l'utilisateur
  • Exigence 1 au niveau du système: étant donné que le système d'inventaire a N article (s) en stock, lorsqu'une demande de N article (s) est entrée dans le système d'inventaire, le système d'inventaire diminue le nombre de stocks pour ce type d'article
  • Exigence 2 au niveau du système: étant donné que le système de paiement a N article (s) en stock, lorsqu'une demande de N article (s) est entrée dans le système de paiement, le système de paiement facture à l'utilisateur pour N article (s)
  • ...
  • Exigence 1 au niveau du programmeur: étant donné que 5 chandails sont en stock, lorsque 3 chandails sont retirés de l'inventaire, puis 2 sièges sont laissés dans l'inventaire
  • ...

Ce type de structure d'exigences permet une conception arborescente où toutes les exigences de niveau programmeur mappent l'arborescence aux exigences de niveau utilisateur. De cette façon, lorsqu'une exigence de niveau programmeur échoue, vous savez quelle exigence de niveau utilisateur est affectée.

En revanche, un test AAA pourrait ressembler à ceci. Pour moi, c'est très orienté programmeur et pas utile à l'entreprise. Cela ne veut pas dire qu'une structure arborescente d'exigences similaire ne pourrait pas être créée à partir d'une stratégie de test AAA, mais rien dans le langage AAA ne le rend plus facile à faire.

public void Test_CaseWhereThereAreEnoughSweatersLeft() {
    // Arrange
    // setup Sweater Inventory mock (DB mocks, etc)
    // count = 5
    // when The number of sweaters remaining is request, return count
    // when Inventory is requested to remove N items, then count = count - N

    // Act
    // call the Unit Under Test to remove 3 items from inventory

    // Assert
    // the number of sweaters in the inventory is 2
    // the removal should return indicating a successful removal of items from the inventory
}

public void Test_CaseWhereThereAreNotEnoughSweatersLeft() {
    // Arrange
    // setup Sweater Inventory mock (DB mocks, etc)
    // count = 2
    // when The number of sweaters remaining is request, return count
    // when Inventory is requested to remove N items, then count = count - N

    // Act
    // call the Unit Under Test to remove 3 items from inventory

    // Assert
    // the number of sweaters remaining is still 2
    // the removal should return an error indicating not enough items in the inventory
}
Frank Bryce
la source
Je trouve toujours intéressant quand les gens se demandent si les ordinateurs (et donc les programmeurs) ajoutent de la valeur à leur entreprise. Serait-ce vraiment un gros bambou égoïste? Je pense qu'un chef d'entreprise doit soit en apprendre suffisamment sur la programmation pour comprendre comment elle atteint ses objectifs, soit simplement avoir confiance en elle et ne pas s'inquiéter. Je ne comprends peut-être pas vraiment comment fonctionne un produit chimique qui influe sur l'apparition du courant redresseur retardé dans les cellules auriculaires, mais je peux certainement sentir à quel point il est bon de ne plus avoir d'arythmie cardiaque.
L'abstraction est importante en dehors de la simple informatique. Les gens auront une expertise dans différents domaines, et être en mesure de communiquer cette expertise avec d'autres est crucial pour une entreprise. GWT est une abstraction qui est utile pour amener les programmeurs et les gestionnaires (de programme | projet) à communiquer. Deuxièmement, en tant que programmeur, il est facile d'imaginer que les programmeurs ont le potentiel de produire peu ou pas de valeur pour une entreprise. Enfin, il convient de noter que GWT n'est pas la seule façon de faire communiquer les programmeurs et les gestionnaires, mais l'un des nombreux outils qu'une entreprise peut vouloir essayer.
Frank Bryce
De plus, je voudrais que mon médecin comprenne pourquoi mon mécanisme de correction de l'arythmie cardiaque fonctionne avant de le mettre en place, et pas seulement qu'il le fasse. Les tests GWT sont censés aider à répondre au «pourquoi». GWT aidant la communication entre le programmeur et le chef de produit est analogue à une communication entre le chimiste et le médecin. Un chef de produit communique aux utilisateurs les fonctionnalités qu'ils obtiennent pendant qu'un médecin communique à leurs patients quelle valeur ils obtiennent avec une correction d'arythmie cardiaque.
Frank Bryce
4

Je suppose que cela dépend du cadre que vous utilisez. En règle générale, autant que je sache, AAA est pris en charge par le cadre NUnit, et est donc le choix naturel à cet égard. Quant aux différences théoriques entre TDD et BDD, elles semblent légères. Voir ce lien, quelqu'un de plus qualifié que moi pour vous donner une explication.

George Grainger
la source
2

Il n'y a aucune différence.
Trois états de test:
Given = Arrange,
When = Act,
Then = Assert.

Les différences que vous avez fournies dans la question sont les différences entre TDD et BDD et non GWT et AAA.

Dans TDD, vous pouvez avoir trois méthodes différentes pour un test

public class TestsOfFormatMethod
{        
    public void Arrange() { // set dependencies }
    public string Act() { // return formattted result }
    public string AssertThatFormatIsEmpty()
    {
        Arrange();
        var actual = Act();
        Assert.IsEmpty(actual);
    }
}
Fabio
la source