Unterschiede zwischen Given When Then (GWT) und Arrange Act Assert (AAA)?

13

In TDD gibt es die Arrange Act Assert (AAA) -Syntax:

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

Bei BDD-Schreibtests wird eine ähnliche Struktur verwendet, jedoch mit der GWT-Syntax (Given When Then):

    [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 */   }

Obwohl sie oft als gleich angesehen werden, gibt es Unterschiede. Einige Schlüssel sind:

  1. GWT kann direkt auf die Spezifikation einer Feature-Datei in BDD-Frameworks abgebildet werden

  2. GWT ist für Nicht-Entwickler einfacher zu verstehen, wenn die Verwendung von einfachem Englisch gefördert wird und eine kurze Beschreibung der einzelnen Teile vorliegt

  3. Given When und Then sind Schlüsselwörter in verschiedenen BDD-Frameworks wie SpecFlow und Cucumber

Meine Frage ist, gibt es andere Unterschiede (außer den Namen) zwischen AAA und GWT? Und gibt es außer den oben genannten noch einen Grund, warum das eine dem anderen vorgezogen werden sollte?

Cognitive_chaos
quelle
3
Ich sehe keinen Unterschied mit Ausnahme der "liest sich eher wie eine natürliche Sprache". Wenn bei einer gegebenen Vereinbarung eine Handlung stattfindet, dann behaupten Sie Dinge über den neuen Zustand. '
Sjoerd Job Postmus
Ich denke, Sie haben ein paar relevante Punkte gefunden und werden wahrscheinlich keine Antwort mit zusätzlichen Unterschieden erhalten. Ich verwende ausschließlich AAA für Unit-Tests, da das Format vollständig methodenunabhängig ist, aber kleine, unabhängige Tests fördert.
amon

Antworten:

9

Ich denke, Sie haben die Unterschiede in Ihrer Frage sehr gut aufgelistet, aber ich werde einige meiner Meinungen dazu hinzufügen, wie ich die beiden Ansätze betrachte.

AAA ist sehr nützlich für mich, wenn ich meinen eigenen Code teste. Wenn ich für mich an einem Projekt oder einer Bibliothek arbeite, bin AAA der Weg, den ich gehe. Damit kann ich alles einrichten, was ich brauche, um meinen Test auszuführen, und ihn dann einfach testen . Es ist schnell einzurichten und schnell zu überprüfen, ob mein Code wie erwartet funktioniert.

GWT ist in Geschäftsumgebungen nützlich, in denen die Arbeit von Programmierern auf den Geschäftswert abgebildet werden muss. Der geschäftliche Nutzen wird durch Funktionen abgebildet, und hoffentlich durch Funktionen, die keine Fehler verursachen. Es gibt viele Strategien zum Zuordnen von Funktionen zu Programmieraufgaben, eine davon sind die Anforderungen. Nach meiner Erfahrung reichen die Anforderungen von Anforderungen auf Benutzerebene bis hin zu kleinen Aufgaben, die der Benutzer ausführen muss. Dies ist nützlich, weil die Manager leicht verstehen können, wie sich die Arbeit des Programmierers auf ihre Kunden / Benutzer auswirkt und warum die Programmierer einen Mehrwert für ihr Geschäft schaffen

  • Anforderung auf Benutzerebene: Wenn das Lager mindestens N Artikel im Inventar hat, liefert das Lager N Artikel an den Benutzer, wenn ein Benutzer N Artikel kauft
  • Anforderung 1 auf Systemebene: Wenn das Inventarsystem N Artikel im Inventar hat und eine Anforderung für N Artikel in das Inventarsystem eingegeben wird, verringert das Inventarsystem die Inventarzahl für diesen Artikeltyp
  • Anforderung 2 auf Systemebene: Wenn das Zahlungssystem N Artikel im Bestand hat und eine Anforderung für N Artikel in das Zahlungssystem eingegeben wird, berechnet das Zahlungssystem dem Benutzer N Artikel.
  • ...
  • Anforderung 1 auf Programmierer-Ebene: Wenn 5 Pullover im Inventar sind und 3 Pullover aus dem Inventar entfernt werden, verbleiben 2 Sitzer im Inventar
  • ...

Diese Art von Anforderungsstruktur ermöglicht ein baumartiges Design, bei dem alle Anforderungen auf Programmiererebene den Baum den Anforderungen auf Benutzerebene zuordnen. Wenn eine Anforderung auf Programmiererebene fehlschlägt, wissen Sie auf diese Weise, welche Anforderung auf Benutzerebene betroffen ist.

Im Gegensatz dazu könnte ein AAA-Test so aussehen. Das ist für mich sehr programmierorientiert und für das Geschäft nicht nützlich. Das heißt nicht, dass mit einer AAA-Teststrategie keine ähnliche Baumstruktur von Anforderungen erstellt werden kann, aber nichts in der Sprache von AAA macht es einfacher, dies zu tun.

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
quelle
Ich finde es immer interessant, wenn Leute sich fragen, ob Computer (und damit Programmierer) einen Mehrwert für ihr Geschäft schaffen. Könnte es wirklich nur eine große, sich selbst dienende Bambusdüse sein? Ich denke, ein Business Manager sollte entweder genug über das Programmieren lernen, um zu verstehen, wie es seine Ziele erreicht, oder einfach darauf vertrauen, dass es funktioniert und sich keine Sorgen macht. Ich verstehe vielleicht nicht wirklich, wie eine Chemikalie, die das Einsetzen des verzögerten Gleichrichterstroms in Vorhofzellen beeinflusst, funktioniert, aber ich kann definitiv spüren, wie gut es ist, keine Herzrhythmusstörung mehr zu haben.
Abstraktion ist außerhalb der Informatik wichtig. Die Mitarbeiter verfügen über Fachkenntnisse in verschiedenen Bereichen, und die Fähigkeit, diese Fachkenntnisse mit anderen zu teilen, ist für ein Unternehmen von entscheidender Bedeutung. GWT ist eine Abstraktion, die nützlich ist, um Programmierer und (Programm- | Projekt-) Manager zur Kommunikation zu bewegen. Zweitens kann man sich als Programmierer leicht vorstellen, dass Programmierer das Potenzial haben, für ein Unternehmen nur einen geringen oder gar keinen Wert zu erzielen. Zu guter Letzt ist zu erwähnen, dass GWT nicht die einzige Möglichkeit ist, Programmierer und Manager zur Kommunikation zu bringen, sondern eines von vielen Tools, die ein Unternehmen ausprobieren möchte.
Frank Bryce
Außerdem möchte ich, dass mein Arzt versteht, warum mein Mechanismus zur Korrektur von Herzrhythmusstörungen funktioniert, bevor sie ihn einsetzen, und nicht nur, dass dies der Fall ist. GWT-Tests sollen helfen, das "Warum" zu beantworten. Die Unterstützung der Kommunikation zwischen Programmierer und Produktmanager durch GWT entspricht der Kommunikation zwischen Chemiker und Arzt. Ein Produktmanager kommuniziert mit den Benutzern, welche Funktionen sie erhalten, während ein Arzt ihren Patienten mitteilt, welchen Wert sie mit einer Herzrhythmusstörungskorrektur erhalten.
Frank Bryce
Ja, ein Facharzt hat das Medikament empfohlen und überwacht, dass es mit mir im Krankenhaus begonnen wird, weil es mich hätte töten können. Mein alter Kardiologe wusste nur, dass es funktionieren könnte, und mein Hausarzt hatte noch nie von der Droge gehört. Es macht noch mehr Spaß, der Versicherungsgesellschaft zu erklären, warum ein Krankenhausaufenthalt von 93.000 US-Dollar medizinisch notwendig war (ein anderer Vorfall), weil sie das Ganze abblasen und mich bezahlen lassen wollten (was bereits geschehen war). Es war mir also ein paar Jahre wert, einen einseitigen Brief schreiben zu können, in dem alles erklärt wurde. Kompetenz rettet Leben. Und Geld.
4

Ich denke, es hängt von dem Framework ab, das Sie verwenden. Nach meinem Verständnis wird AAA im Allgemeinen vom NUnit-Framework unterstützt und ist daher die natürliche Wahl in dieser Hinsicht. Die theoretischen Unterschiede zwischen TDD und BDD scheinen gering zu sein. Sehen Sie diesen Link, jemand, der besser als ich ist, um Ihnen eine Erklärung zu geben.

George Grainger
quelle
2

Es gibt überhaupt keinen Unterschied.
Drei Testzustände :
Gegeben = Anordnen,
Wann
= Handeln , Dann = Bestätigen.

Unterschiede, die Sie in der Frage angegeben haben, sind Unterschiede zwischen TDD und BDD und nicht zwischen GWT und AAA.

In TDD können Sie drei verschiedene Methoden für einen Test haben

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
quelle