Uma novidade na cantina
A escola começou a aceitar encomendas maiores para reuniões e eventos internos. Nesses pedidos existe uma taxa de entrega interna de R$ 5,00.
A nova regra é simples: pedidos com subtotal a partir de R$ 100,00 não pagam a taxa de entrega.
A função que calcula essa taxa ainda não existe.
Normalmente poderíamos implementá-la e só depois testar. Mas existe outra maneira de trabalhar: transformar primeiro a regra em um exemplo executável.
Antes de programar, deixe o comportamento claro
Vamos começar com três situações que deixam a fronteira da regra visível:
| Subtotal | Taxa esperada | Por quê? |
|---|---|---|
| R$ 99,99 | R$ 5,00 | Ainda está abaixo do limite. |
| R$ 100,00 | R$ 0,00 | É exatamente o início da gratuidade. |
| R$ 150,00 | R$ 0,00 | Está acima do limite. |
Perceba que estamos reaproveitando uma técnica anterior: análise de valores-limite. TDD não substitui o que aprendemos; ele pode usar esse raciocínio.
Escrevendo o primeiro teste
Continue na mesma cópia do projeto usada na Etapa 11. Na pasta tests, crie o arquivo test_entrega.py com este conteúdo:
from backend.app import calcular_taxa_entrega
def test_subtotal_de_100_deve_ter_entrega_gratis():
assert calcular_taxa_entrega(100) == 0Agora execute o pytest do mesmo modo que na etapa anterior.
python -m pytestSe estiver no Windows e não tiver ativado o ambiente virtual, use .venv\Scripts\python.exe -m pytest.
A função calcular_taxa_entrega ainda não existe. Por isso, o pytest pode mostrar um erro de importação durante a coleta dos testes, em vez de uma comparação marcada apenas como FAILED. Isso é esperado neste primeiro passo: o comportamento que o teste pede ainda não existe.
O importante é saber por que a execução está vermelha. Não queremos qualquer erro; queremos uma execução que não fica verde porque o comportamento desejado ainda não foi implementado.
RED: primeiro vemos a execução falhar pelo motivo esperado
No ciclo mais conhecido do TDD, o primeiro estado costuma ser chamado de RED, palavra inglesa para “vermelho”. Ele representa uma situação em que o teste ainda não pode ser satisfeito.
Se a execução falhar por caminho de arquivo errado, erro de digitação ou outro ruído que não tenha relação com a regra nova, corrija esse ruído antes de continuar.
GREEN: escrever apenas o suficiente para passar
Abra backend/app.py e acrescente a função abaixo junto das demais funções de regra:
def calcular_taxa_entrega(subtotal):
if subtotal >= 100:
return 0
return 5Execute os testes novamente. Quando o novo teste passar, chegamos ao estado chamado GREEN, “verde”: o comportamento testado foi atendido.
Mas um teste só ainda é pouco
No mesmo arquivo tests/test_entrega.py, acrescente:
def test_abaixo_de_100_deve_cobrar_taxa():
assert calcular_taxa_entrega(99.99) == 5
def test_acima_de_100_deve_ter_entrega_gratis():
assert calcular_taxa_entrega(150) == 0Agora temos uma pequena rede de proteção em torno da regra.
REFACTOR: melhorar sem mudar o comportamento
Depois que os testes passam, podemos melhorar a estrutura do código sem alterar o resultado esperado. Essa etapa é chamada de REFACTOR, de refactoring, ou refatoração.
Por exemplo, podemos retirar números importantes de dentro da função:
TAXA_ENTREGA = 5
LIMITE_ENTREGA_GRATIS = 100
def calcular_taxa_entrega(subtotal):
if subtotal >= LIMITE_ENTREGA_GRATIS:
return 0
return TAXA_ENTREGADepois da mudança, execute a suíte novamente. Se continuar verde, temos evidência de que a refatoração preservou aqueles comportamentos.
Agora podemos dar nome ao ciclo
Desenvolvimento Guiado por Testes (Test-Driven Development — TDD)
É uma abordagem de desenvolvimento em que escrevemos um teste para um pequeno comportamento antes de implementar esse comportamento, fazemos o teste passar e então melhoramos o código mantendo os testes verdes.
TDD não significa “escrever qualquer teste primeiro”
O teste precisa representar um comportamento pequeno e compreensível. Se começarmos com uma enorme sequência que envolve tela, servidor, banco e várias regras ao mesmo tempo, teremos dificuldade para saber o que realmente estamos guiando.
Por isso, TDD costuma funcionar melhor em passos pequenos.
TDD também não garante tudo
Podemos ter vários testes verdes e ainda deixar problemas de usabilidade, desempenho, integração ou requisitos mal compreendidos.
TDD ajuda a desenvolver comportamentos com feedback rápido. Não é um certificado de que o produto inteiro está correto.
Isso se conecta ao que já vimos sobre níveis de teste: uma função pode passar sozinha e ainda falhar quando precisa conversar com outras partes.
Prática · uma nova regra antes do código
A cantina propõe outra mudança:
Pedidos com subtotal a partir de R$ 25,00 recebem R$ 5,00 de desconto promocional.
Crie primeiro os testes para R$ 24,99, R$ 25,00 e R$ 40,00. Dê um nome claro à nova função, execute para obter o RED esperado, implemente o mínimo necessário no backend/app.py, alcance o GREEN e só então refatore se houver algo que possa ficar mais claro.
O teste passou. O sistema inteiro está protegido?
A função pode calcular corretamente a taxa ou o desconto, mas a tela pode enviar dados errados, o servidor pode interpretar outra estrutura e o banco pode não registrar o resultado.
Como testar quando o problema está na conversa entre as partes do sistema?
Antes de seguir
Você deve conseguir explicar:
- o que significa Desenvolvimento Guiado por Testes (TDD);
- o papel de RED, GREEN e REFACTOR no ciclo;
- por que um teste pode começar vermelho porque o comportamento ainda não existe;
- por que TDD não substitui testes de integração, sistema e características não funcionais.