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

11

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. Alcuni di quelli chiave sono:

  1. GWT può essere mappato direttamente alle specifiche di un file di feature in framework BDD

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

  3. Dato When e Then 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?

    
posta Cognitive_chaos 23.01.2016 - 20:50
fonte

3 risposte

7

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

AAA è molto utile per me quando sto testando il mio codice. Se sto lavorando su un progetto o una libreria per me stesso, AAA è il modo in cui vado. Mi consente di configurare tutto ciò di cui ho bisogno per eseguire il mio test e poi basta testarlo . È veloce da configurare e veloce per verificare che il mio codice funzioni come previsto.

GWT è utile negli ambienti aziendali, in cui il lavoro svolto dai programmatori deve essere associato al valore aziendale. Il valore aziendale è mappato per caratteristiche e, auspicabilmente, funzionalità che non introducono bug. Esistono molte strategie per mappare le funzionalità ai task di programmazione, ma uno di questi è attraverso i requisiti. Nella mia esperienza, i requisiti vanno dai requisiti a livello utente fino a piccoli compiti che l'utente deve eseguire. Ciò è utile perché è facile per i manager capire come il lavoro che sta facendo il 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, il magazzino spedisce N articoli all'utente
  • Requisito a livello di sistema 1: Dato che il sistema di inventario ha N articoli nell'inventario, quando una richiesta di N item viene inserita nel sistema di inventario, il sistema di inventario diminuisce il numero di inventario per quel tipo di articolo
  • Requisito 2 a livello di sistema: dato che il sistema di pagamento contiene N articoli nell'inventario, quando una richiesta di N articoli viene inserita nel sistema di pagamento, il sistema di pagamento addebita all'utente per N articolo / i
  • ...
  • Requisito di livello del programmatore 1: Dato che 5 maglioni sono nell'inventario, quando 3 maglioni vengono rimossi dall'inventario, 2 posti sono lasciati nell'inventario
  • ...

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

Al contrario, un test AAA potrebbe assomigliare a questo. Questo per me è molto orientato al programmatore e non è utile per il business. Ciò non significa che una simile struttura ad albero dei requisiti non possa essere fatta da una strategia di test AAA, ma nulla nella lingua 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
}
    
risposta data 27.01.2016 - 17:10
fonte
4

Penso che dipenda dal framework che stai usando. In generale, per quanto ho capito, AAA è supportato dal framework NUnit, e quindi è la scelta naturale a tale riguardo. Per quanto riguarda le differenze teoriche tra TDD e BDD, sembrano leggere. Vedi questo link, qualcuno più qualificato di me per darti una spiegazione.

    
risposta data 27.01.2016 - 14:29
fonte
1

Non c'è alcuna differenza.
Tre stati di prova:
Given = Disponi,
Quando = agisci,
Quindi = Assert.

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);
    }
}
    
risposta data 19.11.2016 - 14:10
fonte

Leggi altre domande sui tag