Given-When-Then — структурни шаблон за описивање тест сценарија, који је BDD преузео из domain-driven design и прилагодио за Behaviour-Driven Development. Формат дели сценарио на три логичка дела: предуслове (Given), радњу (When) и очекивани резултат (Then). Према Мартину Фаулеру (2023), 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, сценарио треба прескочити или припремити тест окружење унапред.
Блок When описује јединствени догађај који покреће тестирано понашање. То може бити позив метода, притискање дугмета, пријем обавештења или одговора са сервера. Кључно правило — један When по сценарију. Ако је потребно проверити низ радњи — креирају се одвојени сценарији, а не ланац When.
// 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 проверава да ли је систем прешао у очекивано стање. Ово укључује: повратне вредности, промене стања објеката, позиве спољних сервиса (путем мок верификације), као и UI промене. Сваки Then блок може садржати неколико провера, али се све односе на једну радњу.
Given-When-Then и Arrange-Act-Assert (AAA) — две варијанте истог троделног шаблона, али са различитом циљном публиком. Разумевање њихових разлика помаже у избору правог формата за конкретан задатак.
| Аспект | Given-When-Then | Arrange-Act-Assert |
|---|---|---|
| Порекло | BDD, пословна анализа | Unit тестирање |
| Језик | Природни (Gherkin) | Код (Kotlin, Swift, Java) |
| Публика | Цео тим + клијент | Програмери |
| Ниво детаљности | Висок ниво | Детаљан |
| Аутоматизација | Cucumber, SpecFlow | JUnit, XCTest, Mockito |
Шаблон Given-When-Then је оптималан за сценарије који се разматрају са клијентом или аналитичарем: критеријуми прихватања функција, сценарији коришћења, регресионе провере. Gherkin синтакса омогућава писање таквих сценарија без знања програмирања.
Arrange-Act-Assert — природан избор за unit тестове који проверавају одређени метод или класу. AAA формат не захтева додатне фрејмворке и ради у било ком програмском језику. За iOS развој, Apple препоручује AAA у документацији XCTest (2024).
Размотримо практичне примере Given-When-Then на Kotlin за Android апликацију. Први пример — тестирање корпе за куповину коришћењем MockK. Други — тест логике 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)
}
}
Други пример демонстрира Given-When-Then са асинхроним кодом. Овде Given задаје стање Firebase Cloud Messaging, When — пријем push обавештења, Then — проверу обраде.
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)
}
}
Трећи пример — BDD сценарио на Gherkin, који показује Given-When-Then у контексту пријемних тестова:
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, креирајте више сценарија где резултат претходног постаје предуслов следећег. Ово чини сценарио атомским и разумљивим.
Given треба да описује суштину, а не конкретне бројеве. Уместо „Given корисник Иванов са стањем 500 рубаља” — „Given корисник са довољним стањем”. Конкретни подаци се премештају у Scenario Outline са табелом Examples. Ово чини сценарио универзалним и поновно употребљивим.
Интеграција 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 је оријентисан на пословни језик и користи се у BDD са Gherkin, а Arrange-Act-Assert је технички формат за unit тестове. Избор зависи од контекста и тима.
Ограничења нема, али се препоручује не више од 3–5 провера по једном Then. Ако има више провера — сценарио вероватно проверава превише у једној радњи. Поделите га на неколико сценарија са различитим Then.
Не. Шаблон се може користити у било ком тест фрејмворку, једноставно делећи тест коментарима или празним редовима на три блока. Gherkin је потребан само ако се сценарији пишу у формату .feature датотека за Cucumber или SpecFlow.
Препоручује се премештање понављајућих предуслова у Background (Gherkin) или @Before методе (JUnit). Ако су предуслови сложени, користите Builder шаблон за креирање тест података. Ово одржава Given кратким и читљивим.
Не. When — обавезни блок који описује радњу. Ако сценарио проверава само стање без радње (нпр. „приликом учитавања апликације подаци треба да буду кеширани”), When описује окидач: „када се апликација покреће”.
Закључак
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође