Behavior-Driven Development (BDD) to metodologia programowania, rozszerzająca TDD poprzez opisywanie zachowania systemu w języku naturalnym. Scenariusze BDD pisane są w formacie Given-When-Then, zrozumiałym zarówno dla programistów, jak i analityków biznesowych. Według Cucumber (2024), BDD eliminuje lukę między wymaganiami klienta a implementacją, przekształcając specyfikacje w wykonywalne testy.
Najważniejsze
Behavior-Driven Development to ewolucja TDD, zaproponowana przez Dana Northa w 2006 roku jako odpowiedź na problem formułowania testów. W TDD programista pisze test, ale pytanie „co dokładnie testować?” pozostaje otwarte. BDD rozwiązuje ten problem, przenosząc nacisk z testowania kodu na opisywanie zachowania systemu z punktu widzenia użytkownika.
Kluczowym novum BDD jest wspólny język dla wszystkich uczestników projektu. Programiści, testerzy, analitycy i klienci omawiają scenariusze w jednolitym języku, który jednocześnie jest wykonywalnym testem. Eliminuje to klasyczny problem „głuchego telefonu”, gdy wymagania tracą sens przy przekazywaniu od analityka do programisty.
Dan North sformułował BDD w 2006 roku w artykule „Introducing BDD” na blogu ThinkCode. Zauważył, że nazwy testów w TDD często formułowane są w kategoriach implementacji („testAddUser”), a nie w kategoriach zachowania („user should be able to register with email”). BDD zastąpił słowo „test” na „should” i „assert” na „expect”, przesuwając nacisk na wartość dla użytkownika.
Według badania Cambridge University (2021), projekty wykorzystujące scenariusze BDD w komunikacji z klientem zmniejszają liczbę błędów w wymaganiach o 35% w porównaniu z tradycyjnymi specyfikacjami w dokumentach tekstowych. Wykonywalne scenariusze nie dopuszczają dwuznacznych sformułowań — każde Given-When-Then albo wykonuje się, albo nie.
Gherkin to język dziedzinowy, używany przez frameworki Cucumber i SpecFlow do opisywania scenariuszy zachowania. Gherkin używa wcięć i słów kluczowych do strukturyzowania scenariuszy, pozostając jednocześnie czytelnym dla osoby bez technicznego zaplecza.
Feature: Login
Scenario: Successful login with valid credentials
Given the user is on the login screen
When they enter valid username and password
Then they should see the home screen
Gherkin definiuje kilka podstawowych słów kluczowych. Feature opisuje funkcjonalność, Scenario — konkretny scenariusz, Given — warunki wstępne, When — akcję, Then — oczekiwany rezultat. Dodatkowo And i But używane są do łączenia kilku warunków.
Pliki Gherkin mają rozszerzenie .feature i są przechowywane w katalogu src/test/resources/features/ w projektach Android. Każdy plik zaczyna się od opisu Feature, po którym następuje jeden lub więcej Scenario. Do parametryzacji używa się Scenario Outline z tabelami Examples — pozwala to uruchomić ten sam scenariusz z różnymi danymi.
Feature: Calculator
Scenario Outline: Addition of two numbers
Given the calculator is running
When I add <a> and <b>
Then the result should be <result>
Examples:
| a | b | result |
| 2 | 3 | 5 |
| 0 | 0 | 0 |
| -1| 1 | 0 |
Given-When-Then to wzorzec strukturalny opisywania scenariuszy, zapożyczony przez BDD z domain-driven design. Każdy scenariusz składa się z trzech części: warunków wstępnych, akcji i oczekiwanego rezultatu. Ten format naturalnie odpowiada Arrange-Act-Assert z testów jednostkowych, ale używa języka zrozumiałego dla biznesu.
Blok Given opisuje stan systemu przed rozpoczęciem scenariusza: jakie dane istnieją, które komponenty są aktywne, w jakim trybie działa aplikacja. W kontekście mobilnym może to być „użytkownik jest zalogowany”, „koszyk nie jest pusty” lub „urządzenie jest w trybie offline”.
Blok When opisuje zdarzenie inicjowane przez użytkownika lub system: naciśnięcie przycisku, otrzymanie push-powiadomienia, odpowiedź serwera. W aplikacjach mobilnych często odpowiada to wywołaniu metody ViewModel lub naciśnięciu elementu UI.
Blok Then opisuje oczekiwaną zmianę stanu: zmianę ekranu, wywołanie API, aktualizację bazy danych. Sprawdzenia w Then powinny być mierzalne i jednoznaczne — stają się asercjami w wykonywalnym kodzie.
BDD i TDD są często mylone, choć to różne poziomy dyscypliny. TDD to technika projektowania na poziomie kodu: „jak napisać implementację”. BDD to technika specyfikacji na poziomie wymagań: „co system powinien robić”.
| Kryterium | TDD | BDD |
|---|---|---|
| Nacisk | Projektowanie API | Zachowanie systemu |
| Język | Kod (JUnit, XCTest) | Naturalny (Gherkin) |
| Odbiorcy | Programiści | Cały zespół + klient |
| Poziom | Testy jednostkowe | Akceptacyjne/integracyjne |
| Rezultat | Pokryte testami API | Wykonywalna specyfikacja |
Najlepsze projekty mobilne używają TDD na poziomie pojedynczych klas (warstwa domain) i BDD na poziomie scenariuszy (warstwa feature). Daje to podwójne pokrycie: TDD gwarantuje poprawność implementacji, BDD — poprawność zrozumienia wymagań. Google we własnej praktyce stosuje kombinację TDD i BDD dla aplikacji Android, jak wskazano w dokumentacji Android Testing (2024).
Ekostystem BDD obejmuje frameworki dla wszystkich popularnych platform i języków programowania mobilnego. Wybór narzędzia zależy od stosu technologicznego i poziomu automatyzacji.
Cucumber to najpopularniejszy framework BDD, działający ze scenariuszami Gherkin. Dla projektów Android używana jest biblioteka io.cucumber:cucumber-android, która integruje się z narzędziami do testowania UI Espresso i Compose Test. Cucumber wspiera Kotlin i Java, co czyni go uniwersalnym wyborem dla studiów używających obu języków.
SpecFlow to framework BDD dla ekosystemu .NET, używany w projektach Xamarin.Forms i .NET MAUI. SpecFlow integruje się z NUnit i xUnit, a jego kroki (step definitions) pisane są w C#. Dla projektów mobilnych SpecFlow pozwala ponownie wykorzystywać scenariusze między wersjami Android i iOS aplikacji na wspólnej bazie kodu.
Dla programowania iOS w Swift istnieją frameworki BDD Quick i Nimble. Quick udostępnia DSL do opisywania scenariuszy w stylu describe/it, a Nimble — matchery z czytelną składnią. Choć te frameworki nie używają Gherkin bezpośrednio, realizują zasadę BDD: opisywanie zachowania w języku zrozumiałym dla całego zespołu.
Rozpatrzmy pełny przykład BDD w projekcie Android: scenariusz składania zamówienia. Najpierw piszemy scenariusz Gherkin, następnie — step definitions w Kotlin.
Metodologia BDD opiera się na spotkaniu three amigos — trzech ról: programisty, testera i analityka. Wspólnie piszą scenariusze przed rozpoczęciem programowania, ustalając wspólne zrozumienie wymagań. Jeśli scenariusz nie przechodzi u żadnego z trzech uczestników — oznacza to, że wymaganie jest sformułowane niejednoznacznie. Ta praktyka opisana jest w książce „Discovery: Explore Behaviour Using Examples” (Gáspár & North, 2021) i jest obowiązkową częścią procesu BDD w dojrzałych zespołach.
Feature: Order Checkout
Scenario: Apply promo code to cart
Given the user has items in the cart
And the total amount is $100
When they apply promo code "WELCOME10"
Then the discount should be $10
And the final total should be $90
Step definitions to kod łączący scenariusz Gherkin z implementacją testową. Każdy krok to metoda z adnotacją odpowiadającą słowu kluczowemu Gherkin.
class CheckoutSteps {
private val cart = Cart()
private val checkout = CheckoutUseCase()
fun `user has items in the cart`() {
cart.addItem(Item("Phone", 100.0))
}
fun `apply promo code`(code: String) {
checkout.applyPromo(cart, code)
}
fun `discount should be`(expected: Double) {
Assertions.assertEquals(expected, checkout.getDiscount())
}
fun `final total should be`(expected: Double) {
Assertions.assertEquals(expected, checkout.getTotal())
}
}
Do uruchamiania testów BDD w projekcie Android używany jest CucumberAndroidJUnitRunner. Skanuje on pliki .feature w zasobach, znajduje odpowiednie step definitions według wyrażeń regularnych i wykonuje scenariusze jako zwykłe testy instrumentalne. Wyniki formatowane są w raport HTML zrozumiały dla klienta.
// build.gradle.kts
dependencies {
androidTestImplementation("io.cucumber:cucumber-android:7.18.0")
androidTestImplementation("io.cucumber:cucumber-junit:7.18.0")
}
// CucumberOptions annotation
@RunWith(Cucumber::class)
@CucumberOptions(features = "features", glue = ["com.app.steps"])
class CucumberTestRunner
Wdrożenie BDD w programowaniu mobilnym wiąże się z szeregiem praktycznych trudności. Świadomość tych problemów pomaga zespołom uniknąć rozczarowania i zbudować stabilny proces BDD.
Głównym problemem jest desynchronizacja między scenariuszami Gherkin a kodem produkcyjnym. Jeśli programiści zmieniają API, nie aktualizując step definitions, pliki .feature przestają odpowiadać implementacji. Rozwiązaniem jest uruchamianie testów BDD w pipeline CI/CD i wymaganie zielonego statusu dla merge request. Praktyka „BDD as a gating mechanism” opisana jest w dokumentacji Cucumber (2024) i stanowi standard w branży.
Scenariusze BDD na Cucumber wykonują się poprzez testy instrumentalne na urządzeniu Android lub emulatorze. Jest to 10–50 razy wolniejsze niż zwykłe testy jednostkowe na JVM. Pojedyncze testowanie akceptacyjne może zajmować 20–30 minut dla dużej aplikacji Android. Zaleca się wydzielenie testów BDD do osobnego zadania CI i uruchamianie ich nocą, a testy jednostkowe — przy każdym pushu. Taka strategia równoważy szybkość informacji zwrotnej i pokrycie scenariuszy.
Przejście na BDD wymaga szkolenia nie tylko programistów, ale też analityków i testerów. Gherkin to prosty język, ale pisanie dobrych scenariuszy wymaga praktyki. Typowe błędy początkujących: zbyt długie scenariusze (ponad 10 kroków), mieszanie Given-When-Then, używanie terminów technicznych w scenariuszach biznesowych. Według BDD Academy (2024), zespoły potrzebują średnio 4–6 sprintów, aby osiągnąć dojrzałość w pisaniu scenariuszy BDD.
Często zadawane pytania
TDD skupia się na projektowaniu API poprzez testy jednostkowe, a BDD — na opisywaniu zachowania systemu poprzez scenariusze w języku naturalnym. BDD rozszerza TDD, dodając wspólny język dla całego zespołu, włączając uczestników nietechnicznych.
Główne frameworki BDD do programowania mobilnego: Cucumber (Android, iOS), SpecFlow (Xamarin, .NET MAUI) i Quick/Nimble (iOS, Swift). Cucumber to najbardziej uniwersalny wybór, wspierający wszystkie popularne platformy.
Gherkin to podstawowy język BDD, ale nie jedyny. Framework iOS Quick używa własnego DSL w Swift. Jednak znajomość Gherkin jest zalecana, ponieważ jest to standard de facto dla projektów międzyplatformowych.
BDD zastępuje tekstowe specyfikacje wykonywalnymi scenariuszami. Klient może sprawdzić scenariusz przed rozpoczęciem programowania, a po realizacji — zobaczyć zielony raport z przejścia. Skraca to cykl informacji zwrotnej i zmniejsza liczbę błędów w wymaganiach.
Tak, BDD to metodologia, a nie narzędzie. Zasady BDD można zrealizować poprzez dowolny framework testowy, nazywając testy w stylu „should do something when condition”. Jednak Cucumber i Gherkin zapewniają spójny język dla całego zespołu.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również