Given-When-Then — is een structureel patroon voor het beschrijven van testscenario's, overgenomen door BDD uit domain-driven design en aangepast voor Behaviour-Driven Development. Het formaat verdeelt het scenario in drie logische delen: voorwaarden (Given), actie (When) en verwacht resultaat (Then). Volgens Martin Fowler (2023) is Given-When-Then niet zomaar een testformaat, maar een denkgereedschap dat de analyse van vereisten en het ontwerpen van scenario's disciplineert vóór de start van de implementatie.
Belangrijkste punten
Given-When-Then — is een patroon voor het beschrijven van gedrag, voor het eerst geformuleerd door Dan North in 2006 als onderdeel van de Behavior-Driven Development-methodologie. Het patroon lost het probleem op van ongestructureerde beschrijvingen van testscenario's, die vaak een mix van voorwaarden, acties en controles in willekeurige volgorde bevatten.
Het hoofdidee van het patroon is scheiding van verantwoordelijkheden tussen de drie blokken. Elk blok is verantwoordelijk voor precies één aspect van het scenario: de toestand ervoor, de gebeurtenis erna en de controle erna. Dit maakt het scenario leesbaar, verifieerbaar en automatiseerbaar. Volgens onderzoek van ontwikkelaars van het Cucumber-framework (2024) vereisen scenario's die strikt het Given-When-Then-patroon volgen 42% minder tijd om te begrijpen door een nieuw teamlid.
Dan North heeft het idee van de driedelige structuur ontleend aan de formulation of tests in TDD en de Test-by-Example-methodologie (gecreëerd door Brian Marick). Marick stelde voor om vereisten te beschrijven via voorbeelden (examples) die tegelijkertijd als tests dienen. Given-When-Then formaliseerde dit idee door ongestructureerde voorbeelden om te zetten in een herhaalbaar patroon.
Het Given-When-Then-patroon wordt niet alleen toegepast in BDD-scenario's in Gherkin, maar ook in gewone unit-tests in JUnit, XCTest en andere frameworks. Commentaren in de code die de test in drie blokken verdelen, zijn een wijdverbreide praktijk om de leesbaarheid van de testbasis te verbeteren. Google beveelt deze aanpak aan in zijn boek „Software Engineering at Google” (2020).
Elk Given-When-Then-blok heeft een strikt gedefinieerde semantiek en invulregels. Overtreding van deze regels leidt tot scenario's die moeilijk te automatiseren of te begrijpen zijn.
Het Given-blok beschrijft de toestand van het systeem vóór het uitvoeren van de te testen actie. Het omvat: bestaande objecten (gebruiker, bestelling, instellingen), actieve toestanden (geautoriseerd, verbonden met netwerk), evenals initiële gegevenswaarden. Elke Given moet verifieerbaar zijn — als de systeemtoestand niet overeenkomt met Given, moet het scenario worden overgeslagen of de testomgeving vooraf worden voorbereid.
Het When-blok beschrijft de enkele gebeurtenis die het te testen gedrag initieert. Dit kan het aanroepen van een methode zijn, het indrukken van een knop, het ontvangen van een melding of antwoord van de server. De belangrijkste regel — één When per scenario. Als een reeks acties moet worden gecontroleerd, worden afzonderlijke scenario's gemaakt, geen When-keten.
// Given: testgegevens aanmaken
val user = User(email = "test@example.com", balance = 500.0)
val product = Product(price = 150.0)
// When: actie uitvoeren
val result = PurchaseUseCase().buy(user, product)
// Then: resultaat controleren
assertEquals(PurchaseResult.Success, result)
assertEquals(350.0, user.balance)
Het Then-blok controleert of het systeem in de verwachte toestand is overgegaan. Dit omvat: retourwaarden, veranderingen in objecttoestand, aanroepen van externe services (via mock-verificatie), evenals UI-veranderingen. Elk Then-blok kan meerdere controles bevatten, maar ze hebben allemaal betrekking op één actie.
Given-When-Then en Arrange-Act-Assert (AAA) — zijn twee varianten van hetzelfde driedelige patroon, maar met een ander doelpubliek. Inzicht in hun verschillen helpt bij het kiezen van het juiste formaat voor een specifieke taak.
| Aspect | Given-When-Then | Arrange-Act-Assert |
|---|---|---|
| Oorsprong | BDD, bedrijfsanalyse | Unit-testen |
| Taal | Natuurlijk (Gherkin) | Code (Kotlin, Swift, Java) |
| Doelpubliek | Hele team + klant | Ontwikkelaars |
| Detailniveau | Hoog niveau | Gedetailleerd |
| Automatisering | Cucumber, SpecFlow | JUnit, XCTest, Mockito |
Het Given-When-Then-patroon is optimaal voor scenario's die worden besproken met de klant of analist: acceptatiecriteria van functies, gebruiksscenario's, regressiecontroles. Gherkin-syntaxis maakt het mogelijk dergelijke scenario's te schrijven zonder programmeerkennis.
Arrange-Act-Assert — is de natuurlijke keuze voor unit-tests die een specifieke methode of klasse controleren. Het AAA-formaat vereist geen extra frameworks en werkt in elke programmeertaal. Voor iOS-ontwikkeling beveelt Apple AAA aan in de XCTest-documentatie (2024).
Laten we praktische voorbeelden van Given-When-Then in Kotlin voor een Android-applicatie bekijken. Het eerste voorbeeld — het testen van een winkelwagentje met MockK. Het tweede — het testen van pushmeldinglogica.
class CartTest {
fun `apply discount when total exceeds threshold`() {
// Given
val cart = Cart()
cart.addItem(Item("Laptop", price = 1000.0))
cart.addItem(Item("Mouse", price = 50.0))
val discount = DiscountCalculator(0.1)
// When
val total = discount.applyIfEligible(cart)
// Then
assertEquals(945.0, total)
assertTrue("Discount was not applied", total < 1050.0)
}
}
Het tweede voorbeeld demonstreert Given-When-Then met asynchrone code. Hier bepaalt Given de status van Firebase Cloud Messaging, When — het ontvangen van een pushmelding, Then — het controleren van de verwerking.
class PushNotificationTest {
fun `handle push notification when app in background`() = runTest {
// Given
val prefs = mockk<SharedPreferences>()
every { prefs.getString("token", null) } returns "fcm-token-abc"
val handler = PushHandler(prefs)
// When
val data = RemoteMessage().apply {
putData("type", "order_update")
putData("order_id", "123")
}
val result = handler.handleNotification(data)
// Then
assertEquals(NotificationAction.OpenOrder("123"), result)
}
}
Het derde voorbeeld — een BDD-scenario in Gherkin, dat Given-When-Then in de context van acceptatietests laat zien:
Feature: User Authorization
Scenario: User cannot login with expired token
Given the user has an expired refresh token
When they try to access the protected profile screen
Then they should see the login screen
And the app should clear all cached data
Effectief gebruik van Given-When-Then vereist naleving van verschillende bewezen praktijken. Ze zorgen voor leesbaarheid, onderhoudbaarheid en automatiseerbaarheid van scenario's.
Strikte regel: één scenario — één actie. Als een reeks van meerdere When moet worden gecontroleerd, maak dan meerdere scenario's, waarbij het resultaat van de vorige de voorwaarde wordt voor de volgende. Dit maakt het scenario atomair en begrijpelijk.
Given moet de essentie beschrijven, niet specifieke cijfers. In plaats van „Given gebruiker Ivanov met saldo van 500 roebel” — „Given gebruiker met voldoende saldo”. Specifieke gegevens worden verplaatst naar Scenario Outline met een tabel Examples. Dit maakt het scenario universeel en herbruikbaar.
Integratie van Given-When-Then-scenario's in de continue integratiepipeline verandert ze van documentatie in bescherming tegen regressies. Elke merge-aanvraag in een mobiel project start automatisch BDD-scenario's en blokkeert samenvoegen als ten minste één scenario faalt.
BDD-scenario's in Cucumber voor Android worden gestart via Gradle-taak ./gradlew cucumber. Voor iOS (Quick/Nimble) — via xcodebuild test. In CI-systemen (GitHub Actions, GitLab CI, Bitrise) worden BDD-tests uitgevoerd op emulators of echte apparaten. Het rapport wordt gegenereerd in HTML-formaat, begrijpelijk voor managers: groene scenario's — geslaagd, rode — mislukt met vermelding van de stap.
.feature-bestanden worden opgeslagen in de repository naast de code en ondergaan code review. De analist maakt een merge-aanvraag met nieuwe scenario's vóór de start van de ontwikkeling (BDD-first). De ontwikkelaar schrijft step definitions en implementatie om deze scenario's groen te maken. Wanneer alle scenario's slagen — is de functionaliteit klaar. Deze aanpak, beschreven in het boek van Gojko Adzic „Specification by Example” (2011), verandert vereisten in een uitvoerbaar artefact.
Veelgestelde vragen
Qua structuur — ja, het is hetzelfde driedelige patroon. Het verschil zit in het doelpubliek: Given-When-Then is gericht op bedrijfstaal en wordt gebruikt in BDD met Gherkin, terwijl Arrange-Act-Assert een technisch formaat is voor unit-tests. De keuze hangt af van de context en het team.
Er zijn geen beperkingen, maar het wordt aanbevolen niet meer dan 3–5 controles per Then. Als er meer controles zijn, test het scenario waarschijnlijk te veel in één actie. Verdeel het in meerdere scenario's met verschillende Then.
Nee. Het patroon kan in elk testframework worden gebruikt, door de test eenvoudig te verdelen met commentaren of lege regels in drie blokken. Gherkin is alleen nodig als de scenario's worden geschreven in .feature-bestandsformaat voor Cucumber of SpecFlow.
Het wordt aanbevolen om herhaalde voorwaarden te verplaatsen naar Background (Gherkin) of @Before-methoden (JUnit). Als de voorwaarden complex zijn, gebruik dan het Builder-patroon voor het maken van testgegevens. Dit houdt Given kort en leesbaar.
Nee. When is een verplicht blok dat de actie beschrijft. Als het scenario alleen de toestand zonder actie controleert (bijvoorbeeld „bij het laden van de applicatie moeten gegevens worden gecachet”), beschrijft When de trigger: „wanneer de applicatie wordt gestart”.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook