Given-When-Then é um padrão estrutural para descrever cenários de teste, emprestado pelo BDD do domain-driven design e adaptado para Behaviour-Driven Development. O formato divide o cenário em três partes lógicas: pré-condições (Given), ação (When) e resultado esperado (Then). De acordo com Martin Fowler (2023), Given-When-Then não é apenas um formato de testes, mas uma ferramenta de pensamento que disciplina a análise de requisitos e o design de cenários antes do início da implementação.
Principais pontos
Given-When-Then é um padrão de descrição de comportamento, formulado pela primeira vez por Dan North em 2006 como parte da metodologia Behavior-Driven Development. O padrão resolve o problema de descrições não estruturadas de cenários de teste, que frequentemente contêm uma mistura de pré-condições, ações e verificações em ordem arbitrária.
A ideia principal do padrão é a separação de responsabilidades entre três blocos. Cada bloco é responsável exatamente por um aspecto do cenário: estado antes, evento durante e verificação depois. Isso torna o cenário legível, verificável e automatizável. De acordo com um estudo dos desenvolvedores do framework Cucumber (2024), cenários que seguem estritamente o padrão Given-When-Then exigem 42% menos tempo para serem compreendidos por um novo membro da equipe.
Dan North pegou emprestada a ideia da estrutura de três partes da formulação de testes em TDD e da metodologia Test-by-Example (criada por Brian Marick). Marick propôs descrever os requisitos através de exemplos (examples) que simultaneamente servem como testes. Given-When-Then formalizou essa ideia, transformando exemplos não estruturados em um padrão repetível.
O padrão Given-When-Then não se aplica apenas em cenários BDD com Gherkin, mas também em testes unitários comuns com JUnit, XCTest e outros frameworks. Comentários no código que dividem o teste em três blocos são uma prática comum para melhorar a legibilidade da base de testes. O Google recomenda essa abordagem em seu livro «Software Engineering at Google» (2020).
Cada bloco do Given-When-Then tem uma semântica estritamente definida e regras de preenchimento. A violação dessas regras produz cenários difíceis de automatizar ou entender.
O bloco Given descreve o estado do sistema antes de executar a ação sob teste. Inclui: objetos existentes (usuário, pedido, configurações), estados ativos (autenticado, conectado à rede) e valores iniciais de dados. Cada Given deve ser verificável — se o estado do sistema não corresponder ao Given, o cenário deve ser pulado ou o ambiente de teste preparado previamente.
O bloco When descreve o único evento que inicia o comportamento sob teste. Pode ser uma chamada de método, um clique em botão, o recebimento de uma notificação ou resposta do servidor. A regra chave é um When por cenário. Se for necessário verificar uma sequência de ações, crie cenários separados, não uma cadeia de When.
// Given: criamos dados de teste
val user = User(email = "test@example.com", balance = 500.0)
val product = Product(price = 150.0)
// When: executamos a ação
val result = PurchaseUseCase().buy(user, product)
// Then: verificamos o resultado
assertEquals(PurchaseResult.Success, result)
assertEquals(350.0, user.balance)
O bloco Then verifica se o sistema transitou para o estado esperado. Isso inclui: valores retornados, mudanças no estado de objetos, chamadas a serviços externos (via verificação de mocks) e alterações na UI. Cada bloco Then pode conter várias verificações, mas todas se referem a uma única ação.
Given-When-Then e Arrange-Act-Assert (AAA) são duas variantes do mesmo padrão de três partes, mas com públicos-alvo diferentes. Entender suas diferenças ajuda a escolher o formato certo para cada tarefa.
| Aspecto | Given-When-Then | Arrange-Act-Assert |
|---|---|---|
| Origem | BDD, análise de negócio | Testes unitários |
| Linguagem | Natural (Gherkin) | Código (Kotlin, Swift, Java) |
| Público | Toda a equipe + cliente | Desenvolvedores |
| Nível de detalhe | Alto nível | Detalhado |
| Automação | Cucumber, SpecFlow | JUnit, XCTest, Mockito |
O padrão Given-When-Then é ideal para cenários discutidos com o cliente ou analista: critérios de aceitação de funcionalidades, casos de uso, verificações de regressão. A sintaxe Gherkin permite escrever esses cenários sem conhecimento de programação.
Arrange-Act-Assert é a escolha natural para testes unitários que verificam um método ou classe específica. O formato AAA não requer frameworks adicionais e funciona em qualquer linguagem de programação. Para desenvolvimento iOS, a Apple recomenda AAA na documentação do XCTest (2024).
Vejamos exemplos práticos de Given-When-Then em Kotlin para uma aplicação Android. O primeiro exemplo é um teste de carrinho de compras usando MockK. O segundo é um teste da lógica de notificações 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)
}
}
O segundo exemplo demonstra Given-When-Then com código assíncrono. Aqui Given define o estado do Firebase Cloud Messaging, When — o recebimento de uma notificação push, Then — a verificação do processamento.
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)
}
}
O terceiro exemplo é um cenário BDD em Gherkin mostrando Given-When-Then no contexto de testes de aceitação:
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
A aplicação eficaz do Given-When-Then requer seguir várias práticas comprovadas. Elas garantem legibilidade, mantenibilidade e automatização dos cenários.
Regra estrita: um cenário — uma ação. Se for necessário verificar uma sequência de vários When, crie vários cenários onde o resultado do anterior se torna pré-condição do próximo. Isso torna o cenário atômico e compreensível.
Given deve descrever a essência, não números concretos. Em vez de «Given o usuário Ivanov com saldo de 500 rublos» — «Given um usuário com saldo suficiente». Os dados concretos são transferidos para o Scenario Outline com uma tabela de Examples. Isso torna o cenário universal e reutilizável.
A integração de cenários Given-When-Then no pipeline de integração contínua os transforma de documentação em proteção contra regressões. Cada merge request em um projeto móvel executa automaticamente os cenários BDD e bloqueia a fusão se pelo menos um cenário falhar.
Cenários BDD com Cucumber para Android são executados através da tarefa Gradle ./gradlew cucumber. Para iOS (Quick/Nimble) — através de xcodebuild test. Em sistemas CI (GitHub Actions, GitLab CI, Bitrise), os testes BDD são executados em emuladores ou dispositivos reais. O relatório é gerado em formato HTML compreensível para gerentes: cenários verdes — aprovados, vermelhos — falha com indicação do passo.
Os arquivos .feature são armazenados no repositório junto ao código e passam por code review. O analista cria um merge request com novos cenários antes do início do desenvolvimento (BDD-first). O desenvolvedor escreve as definições de passos (step definitions) e a implementação para que esses cenários se tornem verdes. Quando todos os cenários passam — a funcionalidade está pronta. Esta abordagem, descrita no livro de Gojko Adzic «Specification by Example» (2011), transforma requisitos em um artefato executável.
Perguntas frequentes
Estruturalmente sim, é o mesmo padrão de três partes. A diferença está no público: Given-When-Then é orientado à linguagem de negócio e usado em BDD com Gherkin, enquanto Arrange-Act-Assert é um formato técnico para testes unitários. A escolha depende do contexto e da equipe.
Não há limite, mas recomenda-se não mais que 3–5 verificações por Then. Se houver mais verificações, o cenário provavelmente está testando muitas coisas em uma única ação. Divida-o em vários cenários com diferentes Then.
Não. O padrão pode ser usado em qualquer framework de teste, simplesmente dividindo o teste com comentários ou linhas em branco em três blocos. Gherkin só é necessário se os cenários forem escritos no formato .feature para Cucumber ou SpecFlow.
Recomenda-se extrair pré-condições repetitivas para Background (Gherkin) ou métodos @Before (JUnit). Se as pré-condições forem complexas, use o padrão Builder para criar dados de teste. Isso mantém Given curto e legível.
Não. When é um bloco obrigatório que descreve a ação. Se o cenário verificar apenas um estado sem ação (por exemplo, «ao carregar o aplicativo os dados devem estar em cache»), When descreve o gatilho: «quando o aplicativo é iniciado».
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também