Differenze tra Given When Then (GWT) e Arrange Act Assert (AAA)?


13

In TDD c'è la sintassi 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);
}

Nei test di scrittura BDD utilizza una struttura simile ma con la sintassi 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 */   }

Sebbene siano spesso considerati uguali, ci sono differenze. Alcune chiave sono:

  1. GWT può essere mappato direttamente alla specifica di un file di funzionalità nei framework BDD

  2. GWT è più facile da capire per i non sviluppatori incoraggiando l'uso dell'inglese semplice e avendo una breve descrizione di ciò che ogni parte sta facendo

  3. Dato quando e poi sono parole chiave in vari framework BDD come SpecFlow e Cucumber

La mia domanda è: ci sono altre differenze (oltre ai nomi) tra AAA e GWT? E c'è qualche motivo oltre a quelli sopra specificati che uno dovrebbe essere preferito rispetto all'altro?


3
Non vedo alcuna differenza tranne che per "legge più come un linguaggio naturale". Dato un accordo, quando si verifica un'azione, quindi affermare le cose sul nuovo stato. '
Sjoerd Job Postmus

Penso che tu abbia trovato un paio di punti rilevanti e che difficilmente riceverai una risposta con differenze aggiuntive. Per quello che vale, uso esclusivamente AAA per test unitari poiché il formato è completamente indipendente dalla metodologia ma incoraggia piccoli test indipendenti.
amon,

Risposte:


9

Penso che tu abbia elencato molto bene le differenze nella tua domanda, tuttavia aggiungerò alcune delle mie opinioni su come vedo i due approcci.

AAA è molto utile per me quando sto testando il mio codice. Se sto lavorando a un progetto o una biblioteca per me, AAA è la strada da percorrere. Mi consente di impostare tutto ciò di cui ho bisogno per eseguire il mio test e poi testarlo . È veloce da configurare e veloce per verificare che il mio codice funzioni come mi aspetto.

GWT è utile in ambienti aziendali, in cui il lavoro svolto dai programmatori deve essere associato al valore aziendale. Il valore aziendale è mappato da funzionalità e, si spera, funzionalità che non introducono bug. Esistono molte strategie per mappare le funzioni alle attività di programmazione, ma una di queste è attraverso i requisiti. Nella mia esperienza, i requisiti vanno dai requisiti a livello di utente fino a piccoli compiti che l'utente deve eseguire. Questo è utile perché è facile per i manager capire come il lavoro del programmatore sta influenzando i loro clienti / utenti, e quindi perché i programmatori stanno aggiungendo valore alla loro attività

  • Requisito a livello di utente: dato che il magazzino ha almeno N articoli in inventario, quando un utente acquista N articoli, quindi il magazzino spedisce N articoli
  • Requisito a livello di sistema 1: dato che il sistema di inventario ha N articoli in inventario, quando una richiesta per N articoli è inserita nel sistema di inventario, il sistema di inventario riduce il conteggio di inventario per quel tipo di articolo
  • Requisito 2 a livello di sistema: dato che il sistema di pagamento ha N articoli in inventario, quando una richiesta per N articoli è inserita nel sistema di pagamento, il sistema di pagamento addebita all'utente articoli N
  • ...
  • Requisito a livello di programmatore 1: dati 5 maglioni sono presenti nell'inventario, quando 3 maglioni vengono rimossi dall'inventario, 2 posti restano nell'inventario
  • ...

Questo tipo di struttura dei requisiti consente una progettazione ad albero in cui tutti i requisiti a livello di programmatore associano l'albero ai requisiti a livello di utente. In questo modo, quando un requisito a livello di programmatore fallisce, si conosce quale requisito a livello di utente è interessato.

Al contrario, un test AAA potrebbe assomigliare a questo. Questo per me è molto rivolto ai programmatori e non è utile per l'azienda. Questo non vuol dire che una struttura ad albero dei requisiti simile non possa essere fatta da una strategia di test AAA, ma nulla nel linguaggio di AAA rende più facile farlo.

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
}

Lo trovo sempre interessante quando le persone si chiedono se i computer (e quindi i programmatori) stanno aggiungendo valore alla loro attività. Potrebbe davvero essere solo un grande bamboozle self-service? Penso che un manager aziendale dovrebbe imparare abbastanza sulla programmazione per capire come sta raggiungendo i propri obiettivi, o semplicemente fidarsi di ciò e non preoccuparsi. Potrei davvero non capire come funziona una sostanza chimica che influenza l'inizio della corrente ritardata del raddrizzatore nelle cellule atriali, ma posso sicuramente sentire quanto sia bello non avere più un'aritmia cardiaca.

L'astrazione è importante al di fuori della sola informatica. Le persone avranno esperienza in diversi settori e poter comunicare tale competenza con gli altri è fondamentale per un'azienda. GWT è un'astrazione utile per far comunicare i programmatori e i gestori (programma | progetto). In secondo luogo, come programmatore è facile immaginare che i programmatori abbiano il potenziale per produrre poco o nessun valore per un'azienda. Infine, vale la pena notare che GWT non è l'unico modo per comunicare programmatori e manager, ma uno dei tanti strumenti che un'azienda potrebbe voler provare.
Frank Bryce,

Inoltre, vorrei che il mio medico capisse perché il mio meccanismo di correzione dell'aritmia cardiaca funziona prima che lo inseriscano, non solo. I test GWT dovrebbero aiutare a rispondere al "perché". GWT aiuta a comunicare tra programmatore e product manager è analogo a una comunicazione tra chimico e medico. Un product manager comunica agli utenti quali sono le loro caratteristiche mentre un medico comunica ai propri pazienti quale valore ottengono con una correzione dell'aritmia cardiaca.
Frank Bryce,

4

Immagino che dipenda dal framework che stai usando. In generale, per quanto ne so, AAA è supportato dal framework NUnit, e quindi è la scelta naturale al riguardo. Per quanto riguarda le differenze teoriche tra TDD e BDD, sembrano essere lievi. Vedi questo link, qualcuno più qualificato di me stesso per darti una spiegazione.


2

Non c'è alcuna differenza.
Tre stati di prova:
dato = organizza,
quando = agisci,
quindi = asserisci.

Le differenze fornite nella domanda sono le differenze tra TDD e BDD e non GWT e AAA.

In TDD puoi avere tre diversi metodi per 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);
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.