Given-When-Then: шта је то, структура сценарија и примери

Аутор: IT Sectr Објављено: 2026-04-10 Време читања: 8 мин

Given-When-Then — структурни шаблон за описивање тест сценарија, који је BDD преузео из domain-driven design и прилагодио за Behaviour-Driven Development. Формат дели сценарио на три логичка дела: предуслове (Given), радњу (When) и очекивани резултат (Then). Према Мартину Фаулеру (2023), Given-When-Then није само формат тестова, већ алат за размишљање који дисциплинује анализу захтева и пројектовање сценарија пре почетка имплементације.

Главно

  • Given-When-Then — шаблон описа сценарија из три блока: контекст, радња, резултат
  • Given задаје почетно стање система и податке пре извршења тестиране радње
  • When описује догађај или радњу која покреће тестирану логику
  • Then проверава очекиване промене стања или повратне вредности
  • Arrange-Act-Assert — еквивалент Given-When-Then у unit тестирању, али без оријентације на пословни језик

Шта је Given-When-Then?

Given-When-Then — шаблон описа понашања, први пут формулисан од стране Dan North 2006. године као део методологије Behavior-Driven Development. Шаблон решава проблем неструктурираних описа тест сценарија, који често садрже мешавину предуслова, радњи и провера у произвољном редоследу.

Основна идеја шаблона — подела одговорности између три блока. Сваки блок је одговоран за тачно један аспект сценарија: стање пре, догађај током и проверу после. Ово чини сценарио читљивим, проверљивим и аутоматизованим. Према истраживању програмера фрејмворка Cucumber (2024), сценарији који се стриктно придржавају шаблона Given-When-Then захтевају 42% мање времена за разумевање од новог члана тима.

Порекло шаблона

Dan North је преузео идеју троделне структуре из formulation of tests у TDD и методологије Test-by-Example (коју је створио Brian Marick). Марик је предложио описивање захтева кроз примере (examples) који истовремено служе као тестови. Given-When-Then је формализовао ову идеју, претварајући неструктуриране примере у поновљиви шаблон.

Област примене

Шаблон Given-When-Then се примењује не само у BDD сценаријима на Gherkin, већ и у обичним unit тестовима на JUnit, XCTest и другим фрејмворцима. Коментари у коду који деле тест на три блока — уобичајена пракса за побољшање читљивости тест базе. Google препоручује овај приступ у својој књизи „Software Engineering at Google” (2020).

Структура три блока

Сваки блок Given-When-Then има строго дефинисану семантику и правила попуњавања. Кршење ових правила доводи до сценарија које је тешко аутоматизовати или разумети.

Given: предуслови

Блок Given описује стање система пре извршења тестиране радње. Укључује: постојеће објекте (корисник, порџбина, подешавања), активна стања (пријављен, повезан на мрежу), као и почетне вредности података. Сваки Given мора бити проверљив — ако стање система не одговара Given, сценарио треба прескочити или припремити тест окружење унапред.

When: радња

Блок When описује јединствени догађај који покреће тестирано понашање. То може бити позив метода, притискање дугмета, пријем обавештења или одговора са сервера. Кључно правило — један When по сценарију. Ако је потребно проверити низ радњи — креирају се одвојени сценарији, а не ланац When.

kotlin
// Given: креирамо тест податке
val user = User(email = "test@example.com", balance = 500.0)
val product = Product(price = 150.0)

// When: извршавамо радњу
val result = PurchaseUseCase().buy(user, product)

// Then: проверавамо резултат
assertEquals(PurchaseResult.Success, result)
assertEquals(350.0, user.balance)

Then: очекивани резултат

Блок Then проверава да ли је систем прешао у очекивано стање. Ово укључује: повратне вредности, промене стања објеката, позиве спољних сервиса (путем мок верификације), као и UI промене. Сваки Then блок може садржати неколико провера, али се све односе на једну радњу.

Given-When-Then и Arrange-Act-Assert

Given-When-Then и Arrange-Act-Assert (AAA) — две варијанте истог троделног шаблона, али са различитом циљном публиком. Разумевање њихових разлика помаже у избору правог формата за конкретан задатак.

АспектGiven-When-ThenArrange-Act-Assert
ПореклоBDD, пословна анализаUnit тестирање
ЈезикПриродни (Gherkin)Код (Kotlin, Swift, Java)
ПубликаЦео тим + клијентПрограмери
Ниво детаљностиВисок нивоДетаљан
АутоматизацијаCucumber, SpecFlowJUnit, XCTest, Mockito

Када користити Given-When-Then

Шаблон Given-When-Then је оптималан за сценарије који се разматрају са клијентом или аналитичарем: критеријуми прихватања функција, сценарији коришћења, регресионе провере. Gherkin синтакса омогућава писање таквих сценарија без знања програмирања.

Када користити Arrange-Act-Assert

Arrange-Act-Assert — природан избор за unit тестове који проверавају одређени метод или класу. AAA формат не захтева додатне фрејмворке и ради у било ком програмском језику. За iOS развој, Apple препоручује AAA у документацији XCTest (2024).

Примери сценарија на Kotlin

Размотримо практичне примере Given-When-Then на Kotlin за Android апликацију. Први пример — тестирање корпе за куповину коришћењем MockK. Други — тест логике push обавештења.

Пример 1: корпа за куповину

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: push обавештења са корутинама

Други пример демонстрира Given-When-Then са асинхроним кодом. Овде Given задаје стање Firebase Cloud Messaging, When — пријем push обавештења, Then — проверу обраде.

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: Gherkin сценарио за аутентификацију

Трећи пример — BDD сценарио на Gherkin, који показује Given-When-Then у контексту пријемних тестова:

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

Најбоље праксе писања сценарија

Ефикасна примена Given-When-Then захтева поштовање неколико проверених пракси. Оне обезбеђују читљивост, одрживост и аутоматизованост сценарија.

Један When по сценарију

Строго правило: један сценарио — једна радња. Ако је потребно проверити низ од неколико When, креирајте више сценарија где резултат претходног постаје предуслов следећег. Ово чини сценарио атомским и разумљивим.

Избегавајте конкретне податке у Given

Given треба да описује суштину, а не конкретне бројеве. Уместо „Given корисник Иванов са стањем 500 рубаља” — „Given корисник са довољним стањем”. Конкретни подаци се премештају у Scenario Outline са табелом Examples. Ово чини сценарио универзалним и поновно употребљивим.

  • Пишите Then као мерљиве тврдње — „корисник треба да види екран за пријаву”, а не „корисник треба да буде преусмерен”
  • Користите And за сличне кораке — ако је потребно неколико Given, обједините их кроз And, не правите други Given
  • Не мешајте нивое апстракције — Given-When-Then треба да буде на истом нивоу: или пословном, или техничком, не помешано
  • Документујте разлог сценарија — коментар на почетку .feature датотеке са описом пословног правила помаже контексту

Given-When-Then у CI/CD пајплајну

Интеграција Given-When-Then сценарија у пајплајн непрекидне интеграције претвара их из документације у заштиту од регресија. Сваки merge request у мобилном пројекту аутоматски покреће BDD сценарије и блокира спајање ако падне бар један сценарио.

Аутоматско покретање сценарија

BDD сценарији на Cucumber за Android се покрећу кроз Gradle задатак ./gradlew cucumber. За iOS (Quick/Nimble) — кроз xcodebuild test. У CI системима (GitHub Actions, GitLab CI, Bitrise) BDD тестови се извршавају на емулаторима или стварним уређајима. Извештај се генерише у HTML формату разумљивом менаџерима: зелени сценарији — положено, црвени — неуспех са назнаком корака.

Жива документација у репозиторијуму

.feature датотеке се чувају у репозиторијуму поред кода и пролазе code review. Аналитичар креира merge request са новим сценаријима пре почетка развоја (BDD-first). Програмер пише дефиниције корака и имплементацију да би ови сценарији постали зелени. Када сви сценарији прођу — функционалност је готова. Овај приступ, описан у књизи Gojko Adzic „Specification by Example” (2011), претвара захтеве у извршни артефакт.

Често постављана питања

Given-When-Then — да ли је то исто што и Arrange-Act-Assert?

По структури — да, ово је исти троделни шаблон. Разлика је у публици: Given-When-Then је оријентисан на пословни језик и користи се у BDD са Gherkin, а Arrange-Act-Assert је технички формат за unit тестове. Избор зависи од контекста и тима.

Колико провера може бити у блоку Then?

Ограничења нема, али се препоручује не више од 3–5 провера по једном Then. Ако има више провера — сценарио вероватно проверава превише у једној радњи. Поделите га на неколико сценарија са различитим Then.

Да ли је обавезно писати Given-When-Then на Gherkin?

Не. Шаблон се може користити у било ком тест фрејмворку, једноставно делећи тест коментарима или празним редовима на три блока. Gherkin је потребан само ако се сценарији пишу у формату .feature датотека за Cucumber или SpecFlow.

Како поступити са дугим предусловима у Given?

Препоручује се премештање понављајућих предуслова у Background (Gherkin) или @Before методе (JUnit). Ако су предуслови сложени, користите Builder шаблон за креирање тест података. Ово одржава Given кратким и читљивим.

Може ли блок When бити празан?

Не. When — обавезни блок који описује радњу. Ако сценарио проверава само стање без радње (нпр. „приликом учитавања апликације подаци треба да буду кеширани”), When описује окидач: „када се апликација покреће”.

Закључак

  • Given-When-Then — троделни шаблон описа сценарија: предуслов, радња, очекивани резултат
  • Given задаје контекст и почетно стање, When — јединствену радњу, Then — проверу резултата
  • Arrange-Act-Assert и Given-When-Then — исти шаблон са различитом публиком и нивоом апстракције
  • Шаблон се примењује у BDD (Gherkin, Cucumber) и у обичним unit тестовима (JUnit, XCTest) кроз коментаре
  • Кључно правило: један When по сценарију — свака радња треба да се проверава одвојено
  • Понављајући предуслови се премештају у Background или @Before методе ради смањења дуплирања
  • Scenario Outline са табелом Examples омогућава параметризацију Given-When-Then са различитим скуповима података без дуплирања кода

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође