Given-When-Then: mi ez, forgatókönyvek szerkezete és példák

Szerző: IT Sectr Megjelenés: 2026-04-10 Olvasási idő: 8 perc

Given-When-Then — egy strukturális minta tesztforgatókönyvek leírására, amelyet a BDD a domain-driven design-ból kölcsönzött és a Behaviour-Driven Development-hez adaptált. A formátum három logikai részre osztja a forgatókönyvet: előfeltételek (Given), cselekvés (When) és várt eredmény (Then). Martin Fowler (2023) szerint a Given-When-Then nem csupán egy tesztformátum, hanem egy gondolkodási eszköz, amely fegyelmezi a követelmények elemzését és a forgatókönyvek tervezését a megvalósítás megkezdése előtt.

Főbb pontok

  • Given-When-Then — forgatókönyv-leírási minta három blokkból: kontextus, cselekvés, eredmény
  • Given meghatározza a rendszer kezdeti állapotát és az adatokat a tesztelt cselekvés végrehajtása előtt
  • When leírja az eseményt vagy cselekvést, amely elindítja a tesztelt logikát
  • Then ellenőrzi az állapot várt változásait vagy a visszaadott értékeket
  • Arrange-Act-Assert — a Given-When-Then megfelelője egységtesztelésben, de üzleti nyelv orientáció nélkül

Mi az a Given-When-Then?

Given-When-Then — egy viselkedésleíró minta, amelyet először Dan North fogalmazott meg 2006-ban a Behavior-Driven Development módszertan részeként. A minta megoldja a strukturálatlan tesztforgatókönyv-leírások problémáját, amelyek gyakran az előfeltételek, cselekvések és ellenőrzések tetszőleges sorrendű keverékét tartalmazzák.

A minta fő ötlete a felelősségi körök szétválasztása a három blokk között. Minden blokk pontosan a forgatókönyv egy aspektusáért felel: az előtti állapotért, a közbeni eseményért és az utáni ellenőrzésért. Ez a forgatókönyvet olvashatóvá, ellenőrizhetővé és automatizálhatóvá teszi. A Cucumber keretrendszer fejlesztőinek kutatása (2024) szerint a Given-When-Then mintát szigorúan követő forgatókönyvek 42%-kal kevesebb időt igényelnek a csapat új tagja általi megértéshez.

A minta eredete

Dan North a háromrészes szerkezet ötletét a TDD-ből származó formulation of tests-ből és a Test-by-Example módszertanból (Brian Marick alkotta) kölcsönözte. Marick azt javasolta, hogy a követelményeket példákon (examples) keresztül írják le, amelyek egyben tesztekként is szolgálnak. A Given-When-Then formalizálta ezt az ötletet, a strukturálatlan példákat ismételhető mintává alakítva.

Alkalmazási terület

A Given-When-Then mintát nemcsak BDD-forgatókönyvekben (Gherkin) alkalmazzák, hanem a szokásos egységtesztekben is, mint a JUnit, XCTest és más keretrendszerek. A kódban lévő megjegyzések, amelyek három blokkra osztják a tesztet, általános gyakorlat a tesztbázis olvashatóságának javítására. A Google ezt a megközelítést ajánlja „Software Engineering at Google” (2020) című könyvében.

A három blokk szerkezete

Minden Given-When-Then blokk szigorúan meghatározott szemantikával és kitöltési szabályokkal rendelkezik. E szabályok megsértése olyan forgatókönyvekhez vezet, amelyeket nehéz automatizálni vagy megérteni.

Given: előfeltételek

A Given blokk leírja a rendszer állapotát a tesztelt cselekvés végrehajtása előtt. Tartalmazza: meglévő objektumokat (felhasználó, rendelés, beállítások), aktív állapotokat (hitelesített, hálózatra csatlakoztatott), valamint az adatok kezdeti értékeit. Minden Given-nek ellenőrizhetőnek kell lennie — ha a rendszer állapota nem felel meg a Given-nek, a forgatókönyvet ki kell hagyni, vagy a tesztkörnyezetet előre fel kell készíteni.

When: cselekvés

A When blokk leírja azt az egyetlen eseményt, amely elindítja a tesztelt viselkedést. Ez lehet metódus meghívása, gomb megnyomása, értesítés vagy szerver válasz fogadása. A kulcsszabály — egy When forgatókönyvenként. Ha cselekvések sorozatát kell ellenőrizni, külön forgatókönyveket kell létrehozni, nem When-láncot.

kotlin
// Given: tesztadatok létrehozása
val user = User(email = "test@example.com", balance = 500.0)
val product = Product(price = 150.0)

// When: cselekvés végrehajtása
val result = PurchaseUseCase().buy(user, product)

// Then: eredmény ellenőrzése
assertEquals(PurchaseResult.Success, result)
assertEquals(350.0, user.balance)

Then: várt eredmény

A Then blokk ellenőrzi, hogy a rendszer a várt állapotba került-e. Ez magában foglalja: visszaadott értékeket, objektumok állapotváltozásait, külső szolgáltatások hívásait (mock-ellenőrzésen keresztül), valamint UI-változásokat. Minden Then blokk több ellenőrzést is tartalmazhat, de mindegyik egyetlen cselekvésre vonatkozik.

Given-When-Then és Arrange-Act-Assert

Given-When-Then és Arrange-Act-Assert (AAA) — ugyanazon háromrészes minta két változata, de eltérő célközönséggel. Különbségeik megértése segít kiválasztani a megfelelő formátumot egy adott feladathoz.

SzempontGiven-When-ThenArrange-Act-Assert
EredetBDD, üzleti elemzésEgységtesztelés
NyelvTermészetes (Gherkin)Kód (Kotlin, Swift, Java)
CélközönségTeljes csapat + ügyfélFejlesztők
Részletesség szintjeMagas szintűRészletes
AutomatizálásCucumber, SpecFlowJUnit, XCTest, Mockito

Mikor használjuk a Given-When-Then-t

A Given-When-Then minta optimális azokhoz a forgatókönyvekhez, amelyeket az ügyféllel vagy elemzővel beszélnek meg: funkciók elfogadási kritériumai, használati forgatókönyvek, regressziós ellenőrzések. A Gherkin szintaxis lehetővé teszi ilyen forgatókönyvek írását programozási ismeretek nélkül.

Mikor használjuk az Arrange-Act-Assert-t

Arrange-Act-Assert — a természetes választás az egységtesztekhez, amelyek egy adott metódust vagy osztályt ellenőriznek. Az AAA formátum nem igényel további keretrendszereket, és bármely programozási nyelvben működik. iOS-fejlesztéshez az Apple az AAA-t ajánlja az XCTest dokumentációjában (2024).

Forgatókönyv-példák Kotlinban

Nézzünk gyakorlati példákat a Given-When-Then-re Kotlinban egy Android-alkalmazáshoz. Az első példa — bevásárlókosár tesztelése MockK használatával. A második — push-értesítések logikájának tesztelése.

1. példa: bevásárlókosár

kotlin
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)
    }
}

2. példa: push-értesítések korutinokkal

A második példa a Given-When-Then-t mutatja be aszinkron kóddal. Itt a Given beállítja a Firebase Cloud Messaging állapotát, a When — a push-értesítés fogadását, a Then — a feldolgozás ellenőrzését.

kotlin
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)
    }
}

3. példa: Gherkin-forgatókönyv hitelesítéshez

A harmadik példa — egy BDD-forgatókönyv Gherkin-ben, amely a Given-When-Then-t mutatja be az elfogadási tesztek kontextusában:

gherkin
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

Legjobb gyakorlatok forgatókönyvek írásához

A Given-When-Then hatékony használata több bevált gyakorlat betartását igényli. Ezek biztosítják a forgatókönyvek olvashatóságát, karbantarthatóságát és automatizálhatóságát.

Egy When forgatókönyvenként

Szigorú szabály: egy forgatókönyv — egy cselekvés. Ha több When sorozatát kell ellenőrizni, hozzon létre több forgatókönyvet, ahol az előző eredménye a következő előfeltételévé válik. Ez atomivá és érthetővé teszi a forgatókönyvet.

Kerülje a konkrét adatokat a Given-ben

A Given-nek a lényeget kell leírnia, nem konkrét számokat. „Given Ivanov felhasználó 500 rubel egyenleggel” helyett — „Given megfelelő egyenleggel rendelkező felhasználó”. A konkrét adatok a Scenario Outline-ba kerülnek a Examples táblával. Ez a forgatókönyvet univerzálissá és újrafelhasználhatóvá teszi.

  • Írja a Then-t mérhető állításokként — „a felhasználónak látnia kell a bejelentkezési képernyőt”, ne „a felhasználót át kell irányítani”
  • Használja az And-et hasonló lépésekhez — ha több Given szükséges, kombinálja őket And-del, ne hozzon létre második Given-t
  • Ne keverje az absztrakciós szinteket — a Given-When-Then egy szinten legyen: vagy üzleti, vagy technikai, ne keverve
  • Dokumentálja a forgatókönyv okát — egy megjegyzés a .feature fájl elején az üzleti szabály leírásával segíti a kontextust

Given-When-Then a CI/CD pipeline-ban

A Given-When-Then forgatókönyvek integrálása a folyamatos integrációs pipeline-ba dokumentációból regresszió elleni védelemmé alakítja őket. Minden egyes merge request egy mobil projektben automatikusan elindítja a BDD-forgatókönyveket, és blokkolja az egyesítést, ha legalább egy forgatókönyv meghiúsul.

Forgatókönyvek automatikus indítása

A BDD-forgatókönyvek Cucumber-ben Androidhoz a Gradle-feladaton ./gradlew cucumber keresztül indulnak. iOS-hez (Quick/Nimble) — xcodebuild test segítségével. CI-rendszerekben (GitHub Actions, GitLab CI, Bitrise) a BDD-tesztek emulátorokon vagy valós eszközökön futnak. A jelentés HTML-formátumban készül, amely a vezetők számára is érthető: zöld forgatókönyvek — sikeres, piros — sikertelen a lépés megjelölésével.

Élő dokumentáció a repository-ban

A .feature fájlok a kód mellett a repository-ban tárolódnak, és code review-n esnek át. Az elemző a fejlesztés megkezdése előtt új forgatókönyvekkel hoz létre merge request-et (BDD-first). A fejlesztő megírja a step definitions-t és a megvalósítást, hogy ezek a forgatókönyvek zöldre váltsanak. Amikor az összes forgatókönyv sikeres — a funkcionalitás kész. Ez a megközelítés, amelyet Gojko Adzic „Specification by Example” (2011) című könyve ír le, a követelményeket végrehajtható artefaktummá alakítja.

Gyakran ismételt kérdések

A Given-When-Then ugyanaz, mint az Arrange-Act-Assert?

Szerkezetét tekintve — igen, ez ugyanaz a háromrészes minta. A különbség a célközönségben van: a Given-When-Then az üzleti nyelvre orientálódik, és BDD-ben használják Gherkin-nel, míg az Arrange-Act-Assert egy technikai formátum egységtesztekhez. A választás a kontextustól és a csapattól függ.

Hány ellenőrzés lehet egy Then blokkban?

Nincs korlátozás, de ajánlott legfeljebb 3–5 ellenőrzés egy Then-enként. Ha több az ellenőrzés, a forgatókönyv valószínűleg túl sokat tesztel egyetlen cselekvéssel. OSSZA fel több forgatókönyvre különböző Then-ekkel.

Kötelező Gherkin-ben írni a Given-When-Then-t?

Nem. A minta bármely tesztkeretrendszerben használható, egyszerűen megjegyzésekkel vagy üres sorokkal három blokkra osztva a tesztet. Gherkin csak akkor szükséges, ha a forgatókönyvek .feature fájl formátumban készülnek Cucumber vagy SpecFlow számára.

Mi a teendő hosszú előfeltételekkel a Given-ben?

Ajánlott az ismétlődő előfeltételeket Background-ba (Gherkin) vagy @Before metódusokba (JUnit) áthelyezni. Ha az előfeltételek összetettek, használja a Builder mintát a tesztadatok létrehozásához. Ez a Given-t rövid és olvasható formában tartja.

Lehet a When blokk üres?

Nem. A When egy kötelező blokk, amely a cselekvést írja le. Ha a forgatókönyv csak az állapotot ellenőrzi cselekvés nélkül (például „a alkalmazás betöltésekor az adatokat gyorsítótárazni kell”), a When leírja a triggert: „amikor az alkalmazás elindul”.

Összegzés

  • Given-When-Then — háromrészes minta forgatókönyvek leírásához: előfeltétel, cselekvés, várt eredmény
  • Given meghatározza a kontextust és a kezdeti állapotot, When — az egyetlen cselekvést, Then — az eredmény ellenőrzését
  • Arrange-Act-Assert és Given-When-Then — ugyanaz a minta eltérő célközönséggel és absztrakciós szinttel
  • A mintát BDD-ben (Gherkin, Cucumber) és szokásos egységtesztekben (JUnit, XCTest) alkalmazzák megjegyzéseken keresztül
  • Kulcsszabály: egy When forgatókönyvenként — minden cselekvést külön kell tesztelni
  • Az ismétlődő előfeltételek a Background-ba vagy @Before metódusokba kerülnek a duplikáció csökkentése érdekében
  • A Scenario Outline a Examples táblával lehetővé teszi a Given-When-Then paraméterezését különböző adatkészletekkel kódismétlés nélkül

Kulcsrakész mobilalkalmazást fejlesztünk

Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.

Projekt megbeszélése

Olvassa el is