Given-When-Then — BDD tərəfindən domain-driven design-dan götürülmüş və Behaviour-Driven Development üçün uyğunlaşdırılmış test ssenarilərini təsvir etmək üçün struktur nümunədir. Format ssenarini üç məntiqi hissəyə ayırır: ilkin şərtlər (Given), hərəkət (When) və gözlənilən nəticə (Then). Martin Fowler (2023)-ə görə, Given-When-Then sadəcə test formatı deyil, həm də tələblərin təhlilini və tətbiqdən əvvəl ssenarilərin layihələndirilməsini intizamlandıran düşüncə alətidir.
Əsas məqamlar
Given-When-Then — ilk dəfə 2006-cı ildə Dan North tərəfindən Behavior-Driven Development metodologiyasının bir hissəsi kimi formalaşdırılmış davranış təsviri nümunəsidir. Nümunə, çox vaxt ilkin şərtlərin, hərəkətlərin və yoxlamaların ixtiyari qaydada qarışığını ehtiva edən qeyri-strukturlaşdırılmış test ssenari təsvirləri problemini həll edir.
Nümunənin əsas ideyası üç blok arasında məsuliyyət bölgüsüdür. Hər blok ssenarinin bir aspektinə cavabdehdir: əvvəlki vəziyyət, hadisə və sonrakı yoxlama. Bu, ssenarini oxunaqlı, yoxlanıla bilən və avtomatlaşdırıla bilən edir. Cucumber çərçivəsinin tərtibatçılarının araşdırmasına (2024) görə, Given-When-Then nümunəsinə ciddi əməl edən ssenarilər komandanın yeni üzvü tərəfindən anlaşılması üçün 42% daha az vaxt tələb edir.
Dan North üçhissəli struktur ideyasını TDD-də formulation of tests və Test-by-Example metodologiyasından (Brian Marick tərəfindən yaradılıb) götürmüşdür. Marick tələbləri eyni zamanda test kimi xidmət edən nümunələr (examples) vasitəsilə təsvir etməyi təklif etmişdir. Given-When-Then bu ideyanı rəsmiləşdirərək qeyri-strukturlaşdırılmış nümunələri təkrarlana bilən nümunəyə çevirmişdir.
Given-When-Then nümunəsi təkcə Gherkin-də BDD ssenarilərində deyil, həm də JUnit, XCTest və digər çərçivələrdə adi vahid testlərində tətbiq olunur. Testi üç bloka ayıran koddakı şərhlər test bazasının oxunaqlılığını yaxşılaşdırmaq üçün geniş yayılmış təcrübədir. Google bu yanaşmanı „Software Engineering at Google” (2020) kitabında tövsiyə edir.
Hər bir Given-When-Then bloku ciddi şəkildə müəyyən edilmiş semantikaya və doldurma qaydalarına malikdir. Bu qaydaların pozulması avtomatlaşdırılması və ya başa düşülməsi çətin olan ssenarilərə gətirib çıxarır.
Given bloku test edilən hərəkətin yerinə yetirilməsindən əvvəl sistemin vəziyyətini təsvir edir. Buraya daxildir: mövcud obyektlər (istifadəçi, sifariş, parametrlər), aktiv vəziyyətlər (icazə verilmiş, şəbəkəyə qoşulmuş), həmçinin ilkin məlumat dəyərləri. Hər bir Given yoxlanıla bilən olmalıdır — əgər sistemin vəziyyəti Given-ə uyğun deyilsə, ssenari buraxılmalı və ya test mühiti əvvəlcədən hazırlanmalıdır.
When bloku test edilən davranışı başladan tək hadisəni təsvir edir. Bu, metodun çağırılması, düymənin basılması, bildirişin və ya serverdən cavabın alınması ola bilər. Əsas qayda — hər ssenari üçün bir When. Hərəkətlər ardıcıllığını yoxlamaq lazımdırsa, When zənciri deyil, ayrı-ayrı ssenarilər yaradılır.
// Given: test məlumatları yaradırıq
val user = User(email = "test@example.com", balance = 500.0)
val product = Product(price = 150.0)
// When: hərəkəti yerinə yetiririk
val result = PurchaseUseCase().buy(user, product)
// Then: nəticəni yoxlayırıq
assertEquals(PurchaseResult.Success, result)
assertEquals(350.0, user.balance)
Then bloku sistemin gözlənilən vəziyyətə keçdiyini yoxlayır. Buraya daxildir: qaytarılan dəyərlər, obyektlərin vəziyyətindəki dəyişikliklər, xarici xidmətlərin çağırışları (mock yoxlaması vasitəsilə), həmçinin UI dəyişiklikləri. Hər Then bloku bir neçə yoxlama ehtiva edə bilər, lakin hamısı bir hərəkətə aiddir.
Given-When-Then və Arrange-Act-Assert (AAA) — eyni üçhissəli nümunənin iki variantıdır, lakin fərqli hədəf auditoriyası ilə. Onların fərqlərini başa düşmək konkret tapşırıq üçün düzgün formatı seçməyə kömək edir.
| Aspekt | Given-When-Then | Arrange-Act-Assert |
|---|---|---|
| Mənşə | BDD, biznes analizi | Vahid test |
| Dil | Təbii (Gherkin) | Kod (Kotlin, Swift, Java) |
| Auditoriya | Bütün komanda + müştəri | Tərtibatçılar |
| Detallaşdırma səviyyəsi | Yüksək səviyyə | Detallı |
| Avtomatlaşdırma | Cucumber, SpecFlow | JUnit, XCTest, Mockito |
Given-When-Then nümunəsi müştəri və ya analitiklə müzakirə edilən ssenarilər üçün optimaldır: funksiyaların qəbul meyarları, istifadə ssenariləri, reqressiya yoxlamaları. Gherkin sintaksisi proqramlaşdırma bilmədən belə ssenariləri yazmağa imkan verir.
Arrange-Act-Assert — konkret metodu və ya sinfi yoxlayan vahid testlər üçün təbii seçimdir. AAA formatı əlavə çərçivələr tələb etmir və istənilən proqramlaşdırma dilində işləyir. iOS inkişafı üçün Apple XCTest (2024) sənədlərində AAA-nı tövsiyə edir.
Android tətbiqi üçün Kotlin dilində Given-When-Then-in praktik nümunələrinə baxaq. Birinci nümunə — MockK istifadə edərək alış-veriş səbətinin test edilməsi. İkinci — push bildirişləri məntiqinin testi.
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)
}
}
İkinci nümunə asinxron kodla Given-When-Then-i nümayiş etdirir. Burada Given Firebase Cloud Messaging vəziyyətini, When — push bildirişinin alınmasını, Then — emalın yoxlanmasını müəyyən edir.
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)
}
}
Üçüncü nümunə — qəbul testləri kontekstində Given-When-Then-i göstərən Gherkin-də BDD ssenarisidir:
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-in effektiv tətbiqi bir neçə sınaqdan keçmiş təcrübəyə riayət etməyi tələb edir. Onlar ssenarilərin oxunaqlılığını, saxlanıla bilməsini və avtomatlaşdırıla bilməsini təmin edir.
Sərt qayda: bir ssenari — bir hərəkət. Bir neçə When ardıcıllığını yoxlamaq lazımdırsa, bir neçə ssenari yaradın, burada əvvəlkinin nəticəsi növbəti üçün ilkin şərt olur. Bu, ssenarini atomar və başa düşülən edir.
Given mahiyyəti təsvir etməlidir, konkret rəqəmləri deyil. „Given istifadəçi İvanov 500 rubl balans ilə” əvəzinə — „Given kifayət qədər balansı olan istifadəçi”. Konkret məlumatlar Examples cədvəli ilə Scenario Outline-a çıxarılır. Bu, ssenarini universal və təkrar istifadə edilə bilən edir.
Given-When-Then ssenarilərinin davamlı inteqrasiya pipeline-na inteqrasiyası onları sənədləşdirmədən reqressiyalardan qorunmağa çevirir. Mobil layihədə hər bir merge request avtomatik olaraq BDD ssenarilərini işə salır və ən azı bir ssenari uğursuz olarsa, birləşməni bloklayır.
Android üçün Cucumber-də BDD ssenariləri Gradle tapşırığı ./gradlew cucumber vasitəsilə işə salınır. iOS (Quick/Nimble) üçün — xcodebuild test vasitəsilə. CI sistemlərində (GitHub Actions, GitLab CI, Bitrise) BDD testləri emulyatorlarda və ya real cihazlarda icra olunur. Hesabat menecerlər üçün başa düşülən HTML formatında hazırlanır: yaşıl ssenarilər — keçdi, qırmızı — addım göstərilməklə uğursuz.
.feature faylları kodla yanaşı repozitoridə saxlanılır və code review-dən keçir. Analitik inkişafa başlamazdan əvvəl yeni ssenarilərlə merge request yaradır (BDD-first). Tərtibatçı bu ssenarilərin yaşıl olması üçün step definitions və tətbiq yazır. Bütün ssenarilər keçdikdə — funksionallıq hazırdır. Gojko Adzic-in „Specification by Example” (2011) kitabında təsvir edilən bu yanaşma tələbləri icra edilə bilən artefakta çevirir.
Tez-tez verilən suallar
Quruluşuna görə — bəli, bu eyni üçhissəli nümunədir. Fərq auditoriyadadır: Given-When-Then biznes dilinə yönəlib və BDD-də Gherkin ilə istifadə olunur, Arrange-Act-Assert isə vahid testlər üçün texniki formatdır. Seçim kontekstdən və komandadan asılıdır.
Məhdudiyyət yoxdur, lakin bir Then üçün 3–5 yoxlamadan çox olmaması tövsiyə olunur. Əgər yoxlamalar çoxdursa, ssenari çox şeyi bir hərəkətlə yoxlayır. Onu fərqli Then ilə bir neçə ssenariyə bölün.
Xeyr. Nümunə istənilən test çərçivəsində istifadə oluna bilər, sadəcə testi şərhlərlə və ya boş sətirlərlə üç bloka ayırmaqla. Gherkin yalnız ssenarilər Cucumber və ya SpecFlow üçün .feature fayl formatında yazıldıqda lazımdır.
Təkrarlanan ilkin şərtləri Background (Gherkin) və ya @Before metodlarına (JUnit) çıxarmaq tövsiyə olunur. İlkin şərtlər mürəkkəbdirsə, test məlumatları yaratmaq üçün Builder nümunəsindən istifadə edin. Bu, Given-i qısa və oxunaqlı saxlayır.
Xeyr. When hərəkəti təsvir edən məcburi blokdur. Əgər ssenari yalnız hərəkətsiz vəziyyəti yoxlayırsa (məsələn, „tətbiq yüklənərkən məlumatlar keşlənməlidir”), When tetikleyiciyi təsvir edir: „tətbiq işə düşdükdə”.
Nəticə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun