Domínio 3 — Claude Code Configuration & Workflows · Lição 5 de 6

Refinamento iterativo: exemplos, testes e interview pattern

Objetivos de aprendizagem

Exemplos concretos vencem prosa ambígua

Quando você descreve uma transformação em prosa ("normalize os números de telefone") e recebe resultados inconsistentes entre execuções, o problema não é capacidade — é ambiguidade: a prosa admite várias interpretações válidas. O exam guide é explícito: exemplos concretos de input/output são a forma mais eficaz de comunicar a transformação esperada. Dois ou três exemplos bem escolhidos eliminam classes inteiras de interpretação errada:

Normalize telefones para E.164 (Brasil como default). Exemplos:

- "(11) 98765-4321"        → "+5511987654321"
- "011 8765 4321"          → "+551187654321"    (fixo, sem 9)
- "+1 (415) 555-0100"      → "+14155550100"     (mantém país explícito)

Se o número for inválido/incompleto, retorne null — não invente dígitos.

Escolha os exemplos como escolheria casos de teste: um caso típico, um caso com formato alternativo e um caso de borda (inclusive o comportamento de erro). Exemplo que só repete o caso óbvio não desambigua nada.

Iteração guiada por testes

O fluxo test-driven com o Claude Code: 1) escreva (ou peça e revise) a suíte de testes cobrindo comportamento esperado, edge cases e requisitos de performance antes da implementação; 2) peça a implementação; 3) rode os testes e compartilhe as falhas literais (nome do teste, assertion, valores esperado/obtido); 4) repita até verde. A falha de teste é o feedback mais objetivo possível — muito superior a "ainda não está certo".

"""Suite escrita ANTES da implementacao — os testes definem o contrato.

Compartilhar a saida do pytest com o Claude a cada iteracao e o passo 3
do ciclo: a falha literal (esperado vs obtido) guia a correcao.
"""
import pytest

from phone import normalize_phone


def test_celular_com_ddd_entre_parenteses():
    assert normalize_phone("(11) 98765-4321") == "+5511987654321"


def test_fixo_sem_nono_digito():
    assert normalize_phone("011 8765 4321") == "+551187654321"


def test_mantem_codigo_de_pais_explicito():
    assert normalize_phone("+1 (415) 555-0100") == "+14155550100"


@pytest.mark.parametrize("invalido", ["", "abc", "119"])
def test_invalido_retorna_none_sem_inventar_digitos(invalido):
    assert normalize_phone(invalido) is None

Note o último teste: edge case com entrada e saída esperada explícitas. É assim que o exame espera que você corrija, por exemplo, valores nulos num script de migração — não com "trate valores nulos direito", e sim com o caso concreto que falha hoje e o resultado esperado.

Interview pattern: perguntas antes de código

Em domínios que você não domina (estratégia de cache, sistemas distribuídos, um subsistema legado), você não sabe o que não sabe — e um prompt direto herda seus pontos cegos. O interview pattern inverte o fluxo: peça ao Claude que faça perguntas antes de implementar ("Antes de escrever código, entreviste-me sobre requisitos, restrições e failure modes que eu deva considerar"). Isso traz à tona considerações que você não tinha antecipado — invalidação de cache, modos de falha, requisitos de consistência — antes de o código existir, quando mudar de rumo é barato.

flowchart TD
    A[Pedido em domínio pouco familiar] --> B[Interview pattern:
Claude pergunta requisitos,
restrições, failure modes] B --> C[Decisões de design explícitas] C --> D[Suíte de testes escrita primeiro
comportamento + edge cases + performance] D --> E[Implementação] E --> F{Testes passam?} F -- Não --> G[Compartilhar falhas literais
esperado vs obtido] G --> E F -- Sim --> H[Concluído]

Uma mensagem ou várias? Problemas que interagem vs independentes

Você revisou a saída e encontrou vários problemas. Como reportar?

SituaçãoEstratégiaPor quê
Os problemas interagem (corrigir um afeta o outro — ex.: o tratamento de timezone e o de formato de data no mesmo parser)Todos numa única mensagem detalhadaCorrigir isoladamente gera soluções que se invalidam mutuamente; o Claude precisa ver o conjunto para desenhar uma correção coerente
Os problemas são independentes (typo na doc, log faltando, teste flaky sem relação)Sequencialmente, um por vezIterações pequenas e verificáveis; cada correção é validada antes da próxima, sem misturar diffs

Pegadinhas da prova

Resumo em 5 linhas

  1. Prosa interpretada de forma inconsistente → 2–3 exemplos concretos de input/output (típico, variante, edge case com comportamento de erro).
  2. Test-driven iteration: suíte primeiro (comportamento, edge cases, performance), depois implementação, depois compartilhar falhas literais até verde.
  3. Edge case quebrado corrige-se com caso de teste específico (entrada + saída esperada), não com pedido genérico.
  4. Interview pattern: em domínio pouco familiar, peça perguntas antes do código — expõe considerações (invalidação de cache, failure modes) que você não anteciparia.
  5. Problemas que interagem → uma única mensagem detalhada; problemas independentes → correções sequenciais verificáveis.

Documentação oficial

Questões de fixação

1. Você pediu "converta os logs para formato estruturado" e cada execução produz um JSON com chaves diferentes. Qual é a correção mais eficaz?

2. Um script de migração gerado pelo Claude falha quando a coluna middle_name é nula. Qual mensagem de refinamento segue a prática do exame?

3. Você vai implementar uma camada de cache para um serviço que não conhece a fundo, e suspeita que existam requisitos (invalidação, consistência, falhas) que você não sabe enumerar. Qual técnica o exame recomenda como primeiro passo?

4. A revisão da implementação de um parser revelou: (1) datas sem timezone tratadas errado e (2) o formato de saída de datas depende do mesmo trecho — mudar um afeta o outro. Também há (3) um typo num comentário. Como reportar?