Definições de Passo
Definições de passo são funções Python que executam passos Gherkin. Bons passos são invólucros finos e reutilizáveis sobre o código da aplicação, e compartilham estado através de fixtures ou objetos de contexto.
Receita
from pytest_bdd import given, when, then, parsers
@given(parsers.parse('um usuário com email "{email}"'))
def user_with_email(email, user_factory):
return user_factory(email=email)
@when("ele faz login")
def login(user_with_email, auth_client):
auth_client.login(user_with_email)
@then(parsers.parse('ele vê "{message}"'))
def see_message(message, page):
assert message in page.contentQuando usar isso:
- Mapeamento de texto Gherkin para execução Python
- Construção de uma biblioteca de passos reutilizáveis
- Análise de parâmetros a partir de texto de passo em linguagem natural
Exemplo de Trabalho
# features/steps/common.py
from pytest_bdd import given, when, then, parsers
import httpx
class APIContext:
def __init__(self):
self.client = None
self.response = None
self.token = None
@given("um cliente de API autenticado")
def auth_client(context: APIContext, test_token):
context.client = httpx.Client(
base_url="http://testserver",
headers={"Authorization": f"Bearer {test_token}"},
)
context.token = test_token
@when(parsers.parse('envio uma requisição {method} para "{path}"'))
def send_request(context: APIContext, method, path):
context.response = context.client.request(method, path)
@then(parsers.parse("o status da resposta é {code:d}"))
def check_status(context: APIContext, code):
assert context.response.status_code == code
@then(parsers.cfparse("a resposta contém {count:d} itens"))
def check_count(context: APIContext, count):
data = context.response.json()
assert len(data) == countO que isto demonstra:
- Objeto de contexto armazena estado por cenário
parsers.parseeparsers.cfparseextraem parâmetros tipados- Passos reutilizáveis compartilhados entre arquivos de feature
- Passos delegam para o código da aplicação, não o reimplementam
Mergulho Profundo
Correspondência de Passos
- Correspondência exata de texto primeiro
parsers.parsepara{nome},{nome:d},{nome:f},{nome:w}(palavra)- A correspondência mais longa vence quando múltiplos passos podem se aplicar
Camadas
Arquivo de feature (o quê)
-> Definição de passo (cola fina)
-> Serviço da aplicação (como)
-> Lógica de domínio
Armadilhas
- Definições de passo gordas - lógica de negócio em passos. Correção: chamar funções de serviço; passos são cola de uma linha.
- Texto de passo ambíguo - múltiplas correspondências. Correção: tornar os passos mais específicos ou usar âncoras de regex.
- Contexto mutável compartilhado - cenário A afeta cenário B. Correção: contexto novo por cenário (escopo da fixture=função).
- Parâmetros tipados como string -
"100"vs100. Correção: usar parsers tipados{amount:f}ou{amount:d}. - Definições de passo duplicadas - erro de registro. Correção: uma definição por texto de passo; compartilhar via importações.
Alternativas
| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
| Passos genéricos | Domínios altamente parametrizados | Passos se tornam ilegíveis |
| Modelo de Objeto de Página | Testes de UI | Projetos apenas de API |
| pytest direto | Sem necessidade de Gherkin | Colaboração com stakeholders necessária |
FAQs
Como passo dados entre passos?
Objeto de contexto, fixtures pytest, ou atributo context do behave.
Passos podem chamar outros passos?
Evitar. Extrair lógica compartilhada em funções auxiliares em vez disso.
Como lidar com tabelas em passos?
pytest-bdd: target_fixture e parâmetro datatable. behave: context.table.
O que é parsers.cfparse?
Formato de análise com mais especificadores de tipo do que o parse básico. Parte do pytest-bdd.
Como reutilizo passos entre projetos?
Publicar um pacote steps/ compartilhado instalado via pip como dependência de desenvolvimento.
Como testo definições de passo?
Chamar a função Python diretamente em testes unitários com contexto simulado.
Passos Given como fixtures?
pytest-bdd suporta target_fixture=True em @given para injetar como fixture.
Como lidar com passos assíncronos?
pytest-bdd com pytest-asyncio: funções de passo async def.
Erro de passo não encontrado?
O texto Gherkin deve corresponder exatamente. Verificar espaços finais e estilo de citação.
Quantos passos compartilhados?
10-20 passos comuns (autenticação, cliente API, asserções). Passos específicos da feature permanecem locais.
Relacionados
- Sintaxe Gherkin - autoria de texto de passo
- Configuração behave / pytest-bdd - configuração do projeto
- Gherkin para Código - fluxo de implementação
- Fixtures - padrões de fixture pytest
Versões da Stack: Esta página foi escrita para Python 3.14.0, FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, e uv 0.6+.