Gherkin é a linguagem por trás do BDD: um conjunto pequeno de palavras-chave que deixa um cenário de teste legível por qualquer pessoa — do Product Owner ao desenvolvedor — e, ao mesmo tempo, executável por ferramentas como Cucumber, Behave (Python), SpecFlow (.NET) ou Behat (PHP). É o ponto onde a especificação e o teste viram o mesmo documento.
As palavras-chave
Toda a gramática cabe em poucas palavras. O resto é texto livre que você escolhe:
- Funcionalidade (
Feature) — o agrupador; descreve a capacidade do sistema. - Cenário (
Scenario) — um exemplo concreto de comportamento. - Dado (
Given) — o contexto / pré-condição. O mundo antes da ação. - Quando (
When) — a ação que dispara o comportamento. Uma só por cenário, idealmente. - Então (
Then) — o resultado observável que se verifica. - E / Mas (
And/But) — encadeiam passos do mesmo tipo, mantendo a leitura fluida.
A estrutura Given-When-Then
O coração do Gherkin é separar contexto → ação → resultado. Essa tríade força o autor a pensar em comportamento, não em telas:
# language: pt
Funcionalidade: Autenticação de usuário
Cenário: Login com credenciais válidas
Dado que estou na página de login
E possuo uma conta com e-mail "ana@exemplo.com"
Quando informo as credenciais corretas
Então devo ver o painel inicial
E devo ver a saudação "Olá, Ana"
Regra de ouro: Given não tem ação, When é uma ação só, Then não tem efeito colateral — só verifica. Se um cenário tem três "Quando", provavelmente são três cenários disfarçados.
Background: o contexto que se repete
Quando vários cenários compartilham os mesmos Given, o Background (Contexto) evita repetição — ele roda antes de cada cenário do arquivo:
Contexto:
Dado que estou logado como administrador
E existe um produto "Caderno" no catálogo
Scenario Outline: um cenário, muitos dados
Para testar a mesma regra com várias entradas — o caso clássico de partição de equivalência e valor-limite — usa-se o Esquema do Cenário com uma tabela de Exemplos:
Esquema do Cenário: Desconto por faixa de valor
Dado um carrinho com <valor> reais
Quando o cliente finaliza a compra
Então o total cobrado deve ser <total> reais
Exemplos:
| valor | total |
| 100 | 100 |
| 101 | 90.9 |
| 150 | 135 |
Cada linha da tabela vira um cenário independente. É a forma mais limpa de cobrir limites (o 100 que não ganha desconto e o 101 que ganha) sem copiar e colar.
Do texto ao código: step definitions
O Gherkin sozinho não testa nada — ele é "colado" ao sistema pelos step definitions: funções que casam com cada passo por expressão e executam a automação de verdade. Em Cucumber com JavaScript:
const { Given, When, Then } = require('@cucumber/cucumber');
const { expect } = require('@playwright/test');
Given('um carrinho com {int} reais', async function (valor) {
this.carrinho = criarCarrinho(valor);
});
When('o cliente finaliza a compra', async function () {
this.total = this.carrinho.finalizar();
});
Then('o total cobrado deve ser {float} reais', async function (esperado) {
expect(this.total).toBeCloseTo(esperado, 2);
});
Repare que o mesmo step um carrinho com {int} reais serve a todas as linhas do Exemplos. Steps bem escritos são reutilizáveis — esse é o ganho de manutenção do BDD.
Declarativo > imperativo
O erro mais comum é escrever cenários imperativos, descrevendo cada clique. Eles quebram a cada ajuste de tela e ninguém do negócio consegue ler:
| Imperativo (frágil) | Declarativo (robusto) |
|---|---|
| Quando preencho o campo "email" com "ana@x.com" E preencho o campo "senha" com "123" E clico no botão "#btn-login" |
Quando faço login com credenciais válidas |
O "como preencher o formulário" pertence ao step definition (e ao Page Object), não ao Gherkin. O cenário descreve a intenção.
Anti-patterns para vigiar
- Cenário-novela: dez passos cobrindo um fluxo inteiro. Um cenário = um comportamento.
- Detalhe de UI no Then: verificar cor de botão ou CSS. Verifique resultado de negócio.
- Acoplamento entre cenários: o cenário 2 depender do estado deixado pelo cenário 1. Cada um deve ser independente.
- Gherkin sem conversa: escrever os
.featuresozinho, depois da implementação. Aí é só relatório enfeitado — perde-se o valor de descoberta do BDD.
Conclusão
Gherkin é simples de propósito: a restrição de vocabulário é o que mantém o cenário legível para todos e estável no tempo. Dominar Given-When-Then, Background e Scenario Outline — e saber escrever de forma declarativa — é o que transforma uma suíte de BDD em documentação viva em vez de mais um conjunto de testes frágeis.
Gherkin is the language behind BDD: a small set of keywords that makes a test scenario readable by anyone, from the Product Owner to the developer, and at the same time executable by tools like Cucumber, Behave (Python), SpecFlow (.NET), or Behat (PHP). It's the point where the specification and the test become the same document.
The keywords
The whole grammar fits in a few words. The rest is free text that you choose:
- Feature — the grouping; describes a capability of the system.
- Scenario — a concrete example of behavior.
- Given — the context / precondition. The world before the action.
- When — the action that triggers the behavior. Just one per scenario, ideally.
- Then — the observable outcome that gets verified.
- And / But — chain steps of the same type, keeping the reading fluid.
The Given-When-Then structure
The heart of Gherkin is separating context → action → outcome. This triad forces the author to think about behavior, not screens:
# language: en
Feature: User authentication
Scenario: Login with valid credentials
Given I am on the login page
And I have an account with the email "ana@example.com"
When I enter the correct credentials
Then I should see the dashboard
And I should see the greeting "Hello, Ana"
Golden rule: Given has no action, When is a single action, Then has no side effects, it only verifies. If a scenario has three "When"s, it's probably three scenarios in disguise.
Background: the context that repeats
When several scenarios share the same Givens, the Background avoids repetition; it runs before each scenario in the file:
Background:
Given I am logged in as an administrator
And a product "Notebook" exists in the catalog
Scenario Outline: one scenario, lots of data
To test the same rule with several inputs (the classic case of equivalence partitioning and boundary values), use the Scenario Outline with an Examples table:
Scenario Outline: Discount by order value
Given a cart with <value> dollars
When the customer checks out
Then the total charged should be <total> dollars
Examples:
| value | total |
| 100 | 100 |
| 101 | 90.9 |
| 150 | 135 |
Each row of the table becomes an independent scenario. It's the cleanest way to cover boundaries (the 100 that gets no discount and the 101 that does) without copy and paste.
From text to code: step definitions
Gherkin alone tests nothing; it gets "glued" to the system by step definitions: functions that match each step by expression and run the actual automation. In Cucumber with JavaScript:
const { Given, When, Then } = require('@cucumber/cucumber');
const { expect } = require('@playwright/test');
Given('a cart with {int} dollars', async function (value) {
this.cart = createCart(value);
});
When('the customer checks out', async function () {
this.total = this.cart.checkout();
});
Then('the total charged should be {float} dollars', async function (expected) {
expect(this.total).toBeCloseTo(expected, 2);
});
Notice that the same step a cart with {int} dollars serves every row of the Examples. Well-written steps are reusable, and that's BDD's maintenance payoff.
Declarative > imperative
The most common mistake is writing imperative scenarios that describe every click. They break with every screen tweak and nobody on the business side can read them:
| Imperative (brittle) | Declarative (robust) |
|---|---|
| When I fill in the "email" field with "ana@x.com" And I fill in the "password" field with "123" And I click the "#btn-login" button |
When I log in with valid credentials |
The "how to fill in the form" belongs to the step definition (and to the Page Object), not to Gherkin. The scenario describes the intent.
Anti-patterns to watch for
- Soap-opera scenario: ten steps covering an entire flow. One scenario = one behavior.
- UI detail in the Then: verifying a button's color or CSS. Verify a business outcome.
- Coupling between scenarios: scenario 2 depending on the state left by scenario 1. Each one must be independent.
- Gherkin without conversation: writing the
.featurefiles alone, after the implementation. That's just a dressed-up report, and you lose the discovery value of BDD.
Conclusion
Gherkin is simple on purpose: the vocabulary restriction is what keeps the scenario readable for everyone and stable over time. Mastering Given-When-Then, Background, and Scenario Outline, and knowing how to write declaratively, is what turns a BDD suite into living documentation instead of one more set of brittle tests.