Given-When-Then — este un șablon structural pentru descrierea scenariilor de test, împrumutat de BDD din domain-driven design și adaptat pentru Behaviour-Driven Development. Formatul împarte scenariul în trei părți logice: precondiții (Given), acțiune (When) și rezultat așteptat (Then). Potrivit lui Martin Fowler (2023), Given-When-Then nu este doar un format de test, ci un instrument de gândire care disciplinează analiza cerințelor și proiectarea scenariilor înainte de începerea implementării.
Principalele puncte
Given-When-Then — este un șablon de descriere a comportamentului, formulat pentru prima dată de Dan North în 2006 ca parte a metodologiei Behavior-Driven Development. Șablonul rezolvă problema descrierilor nestructurate ale scenariilor de test, care conțin adesea un amestec de precondiții, acțiuni și verificări într-o ordine arbitrară.
Ideea principală a șablonului este separarea responsabilităților între cele trei blocuri. Fiecare bloc răspunde pentru exact un aspect al scenariului: starea înainte, evenimentul în timpul și verificarea după. Aceasta face scenariul lizibil, verificabil și automatizabil. Potrivit cercetării dezvoltatorilor framework-ului Cucumber (2024), scenariile care urmează strict șablonul Given-When-Then necesită cu 42% mai puțin timp pentru înțelegere de către un nou membru al echipei.
Dan North a împrumutat ideea structurii în trei părți din formulation of tests în TDD și metodologia Test-by-Example (creată de Brian Marick). Marick a propus descrierea cerințelor prin exemple (examples) care servesc simultan drept teste. Given-When-Then a formalizat această idee, transformând exemplele nestructurate într-un șablon repetabil.
Șablonul Given-When-Then se aplică nu numai în scenariile BDD în Gherkin, ci și în testele unitare obișnuite în JUnit, XCTest și alte framework-uri. Comentariile în cod care împart testul în trei blocuri sunt o practică răspândită pentru îmbunătățirea lizibilității bazei de testare. Google recomandă această abordare în cartea sa „Software Engineering at Google” (2020).
Fiecare bloc Given-When-Then are o semantică strict definită și reguli de completare. Încălcarea acestor reguli duce la scenarii care sunt greu de automatizat sau de înțeles.
Blocul Given descrie starea sistemului înainte de executarea acțiunii testate. Include: obiecte existente (utilizator, comandă, setări), stări active (autentificat, conectat la rețea), precum și valori inițiale ale datelor. Fiecare Given trebuie să fie verificabil — dacă starea sistemului nu corespunde Given, scenariul trebuie omis sau mediul de test trebuie pregătit în prealabil.
Blocul When descrie un singur eveniment care inițiază comportamentul testat. Acesta poate fi apelarea unei metode, apăsarea unui buton, primirea unei notificări sau a unui răspuns de la server. Regula cheie — un When per scenariu. Dacă trebuie verificată o succesiune de acțiuni — se creează scenarii separate, nu un lanț de When.
// Given: creăm date de test
val user = User(email = "test@example.com", balance = 500.0)
val product = Product(price = 150.0)
// When: executăm acțiunea
val result = PurchaseUseCase().buy(user, product)
// Then: verificăm rezultatul
assertEquals(PurchaseResult.Success, result)
assertEquals(350.0, user.balance)
Blocul Then verifică dacă sistemul a trecut în starea așteptată. Aceasta include: valori returnate, modificări ale stării obiectelor, apeluri ale serviciilor externe (prin verificare mock), precum și modificări UI. Fiecare bloc Then poate conține mai multe verificări, dar toate se referă la o singură acțiune.
Given-When-Then și Arrange-Act-Assert (AAA) — sunt două variante ale aceluiași șablon în trei părți, dar cu audiență țintă diferită. Înțelegerea diferențelor lor ajută la alegerea formatului potrivit pentru o sarcină specifică.
| Aspect | Given-When-Then | Arrange-Act-Assert |
|---|---|---|
| Origine | BDD, analiză de afaceri | Testare unitară |
| Limbaj | Natural (Gherkin) | Cod (Kotlin, Swift, Java) |
| Audiență | Întreaga echipă + client | Dezvoltatori |
| Nivel de detaliu | La nivel înalt | Detaillat |
| Automatizare | Cucumber, SpecFlow | JUnit, XCTest, Mockito |
Șablonul Given-When-Then este optim pentru scenarii care sunt discutate cu clientul sau analistul: criterii de acceptare a funcționalităților, scenarii de utilizare, verificări de regresie. Sintaxa Gherkin permite scrierea unor astfel de scenarii fără cunoștințe de programare.
Arrange-Act-Assert — este alegerea naturală pentru testele unitare care verifică o metodă sau o clasă specifică. Formatul AAA nu necesită framework-uri suplimentare și funcționează în orice limbaj de programare. Pentru dezvoltarea iOS, Apple recomandă AAA în documentația XCTest (2024).
Să analizăm exemple practice de Given-When-Then în Kotlin pentru o aplicație Android. Primul exemplu — testarea coșului de cumpărături folosind MockK. Al doilea — testul logicii de notificări push.
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)
}
}
Al doilea exemplu demonstrează Given-When-Then cu cod asincron. Aici Given stabilește starea Firebase Cloud Messaging, When — primirea notificării push, Then — verificarea procesării.
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)
}
}
Al treilea exemplu — un scenariu BDD în Gherkin, care arată Given-When-Then în contextul testelor de acceptare:
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
Utilizarea eficientă a Given-When-Then necesită respectarea mai multor practici dovedite. Acestea asigură lizibilitatea, mentenabilitatea și automatizabilitatea scenariilor.
Regulă strictă: un scenariu — o acțiune. Dacă trebuie verificată o succesiune de mai multe When, creează mai multe scenarii, unde rezultatul precedentului devine precondiția următorului. Aceasta face scenariul atomic și ușor de înțeles.
Given trebuie să descrie esența, nu cifre concrete. În loc de „Given utilizatorul Ivanov cu soldul de 500 de ruble” — „Given utilizatorul cu sold suficient”. Datele concrete se mută în Scenario Outline cu tabelul Examples. Aceasta face scenariul universal și reutilizabil.
Integrarea scenariilor Given-When-Then în pipeline-ul de integrare continuă le transformă din documentație în protecție împotriva regresiunilor. Fiecare cerere de merge într-un proiect mobil rulează automat scenariile BDD și blochează îmbinarea dacă cel puțin un scenariu eșuează.
Scenariile BDD în Cucumber pentru Android se rulează prin task-ul Gradle ./gradlew cucumber. Pentru iOS (Quick/Nimble) — prin xcodebuild test. În sistemele CI (GitHub Actions, GitLab CI, Bitrise) testele BDD se execută pe emulatoare sau dispozitive reale. Raportul se generează în format HTML, ușor de înțeles pentru manageri: scenarii verzi — promovate, roșii — eșec cu indicarea pasului.
Fișierele .feature sunt stocate în repository lângă cod și trec prin code review. Analistul creează o cerere de merge cu scenarii noi înainte de începerea dezvoltării (BDD-first). Dezvoltatorul scrie step definitions și implementarea pentru ca aceste scenarii să devină verzi. Când toate scenariile trec — funcționalitatea este gata. Această abordare, descrisă în cartea lui Gojko Adzic „Specification by Example” (2011), transformă cerințele într-un artefact executabil.
Întrebări frecvente
Ca structură — da, este același șablon în trei părți. Diferența constă în audiență: Given-When-Then este orientat către limbajul de afaceri și este folosit în BDD cu Gherkin, iar Arrange-Act-Assert este un format tehnic pentru testele unitare. Alegerea depinde de context și de echipă.
Nu există limitări, dar se recomandă nu mai mult de 3–5 verificări pentru un Then. Dacă verificările sunt mai multe, scenariul probabil testează prea multe într-o singură acțiune. Împarte-l în mai multe scenarii cu Then diferite.
Nu. Șablonul poate fi folosit în orice framework de testare, doar împărțind testul cu comentarii sau linii goale în trei blocuri. Gherkin este necesar doar dacă scenariile sunt scrise în formatul fișierelor .feature pentru Cucumber sau SpecFlow.
Se recomandă mutarea precondițiilor repetitive în Background (Gherkin) sau metodele @Before (JUnit). Dacă precondițiile sunt complexe, folosește șablonul Builder pentru crearea datelor de test. Aceasta menține Given scurt și lizibil.
Nu. When este un bloc obligatoriu care descrie acțiunea. Dacă scenariul verifică doar starea fără acțiune (de exemplu, „la încărcarea aplicației datele trebuie să fie stocate în cache”), When descrie declanșatorul: „când aplicația se pornește”.
Concluzii
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și