{
 "grupo": "testes",
 "descricao": "Testes e qualidade",
 "itens": [
  {
   "id": "testes-mock-so-na-fronteira",
   "nome": "Mock só na fronteira",
   "receita": "substitua rede, disco e relógio por dublês; a lógica própria roda de verdade",
   "prova": "o teste passa sem rede e quebra se a regra de negócio mudar"
  },
  {
   "id": "testes-stub-de-relogio",
   "nome": "Stub de relógio",
   "receita": "injete o relógio ou use fake timers; avance o tempo no teste em vez de esperar",
   "prova": "expiração de 24 h testada em milissegundos"
  },
  {
   "id": "testes-fixture-com-fabrica",
   "nome": "Fixture com fábrica",
   "receita": "funções que montam objetos válidos com sobrescrita só do que importa ao caso",
   "prova": "cada teste mostra só os campos relevantes"
  },
  {
   "id": "testes-teste-de-caracterizacao",
   "nome": "Teste de caracterização",
   "receita": "rode o código legado, grave a saída atual como esperada e só então refatore",
   "prova": "a suíte fica verde antes e depois da mudança"
  },
  {
   "id": "testes-teste-orientado-a-tabela",
   "nome": "Teste orientado a tabela",
   "receita": "uma lista de entradas e saídas esperadas percorrida por um único teste",
   "prova": "casos de borda novos entram como uma linha"
  },
  {
   "id": "testes-teste-de-propriedade",
   "nome": "Teste de propriedade",
   "receita": "gere entradas aleatórias (fast-check, Hypothesis) e afirme invariantes como \"decodificar(codificar(x)) == x\"",
   "prova": "a biblioteca acha e reduz um contraexemplo"
  },
  {
   "id": "testes-teste-de-snapshot-com-criterio",
   "nome": "Teste de snapshot com critério",
   "receita": "snapshot só de saída pequena e estável; revise cada diff e nunca atualize às cegas",
   "prova": "mudança intencional aparece no diff do PR"
  },
  {
   "id": "testes-teste-flaky-achar-a-causa",
   "nome": "Teste flaky: achar a causa",
   "receita": "rode 50 vezes em laço, isole ordem, relógio, rede e concorrência, depois corrija a causa",
   "prova": "50 execuções seguidas verdes"
  },
  {
   "id": "testes-isolar-testes-de-ordem",
   "nome": "Isolar testes de ordem",
   "receita": "cada teste cria e limpa seus dados; rode em ordem aleatória",
   "prova": "a suíte passa com --shuffle"
  },
  {
   "id": "testes-banco-real-nos-testes",
   "nome": "Banco real nos testes",
   "receita": "container do mesmo motor, transação revertida por teste ou schema por worker",
   "prova": "os testes de repositório rodam contra o banco de verdade"
  },
  {
   "id": "testes-teste-de-contrato-entre-servicos",
   "nome": "Teste de contrato entre serviços",
   "receita": "consumidor define o contrato (Pact), provedor o verifica no CI",
   "prova": "mudar um campo no provedor quebra o teste do contrato"
  },
  {
   "id": "testes-teste-de-api",
   "nome": "Teste de API",
   "receita": "chame o endpoint de verdade (supertest, httpx) e confira status, corpo e cabeçalhos",
   "prova": "cada rota tem caso feliz, 400, 401 e 404"
  },
  {
   "id": "testes-teste-e2e-do-fluxo-critico",
   "nome": "Teste E2E do fluxo crítico",
   "receita": "cubra login, compra ou cadastro de ponta a ponta com dados criados por API",
   "prova": "fluxo roda 3 vezes seguidas sem falha"
  },
  {
   "id": "testes-seletores-estaveis-em-e2e",
   "nome": "Seletores estáveis em E2E",
   "receita": "getByRole, getByLabel ou data-testid; nunca classe de estilo ou posição",
   "prova": "trocar o CSS não quebra o teste"
  },
  {
   "id": "testes-esperas-sem-sleep",
   "nome": "Esperas sem sleep",
   "receita": "espere por estado (elemento visível, resposta de rede) com auto-wait",
   "prova": "não existe sleep fixo no teste"
  },
  {
   "id": "testes-teste-visual-de-regressao",
   "nome": "Teste visual de regressão",
   "receita": "capture screenshots em viewport fixo, fontes embutidas e tolerância pequena; revise os diffs",
   "prova": "a mudança visual aparece como diff aprovado ou recusado"
  },
  {
   "id": "testes-cobertura-que-significa-algo",
   "nome": "Cobertura que significa algo",
   "receita": "meça cobertura de ramos nas regras de negócio e use mutation testing para provar que os testes pegam erro",
   "prova": "mutantes sobreviventes listados e corrigidos"
  },
  {
   "id": "testes-mutation-testing",
   "nome": "Mutation testing",
   "receita": "rode Stryker ou mutmut no módulo, e escreva teste para cada mutante que sobrevive",
   "prova": "score de mutação sobe no módulo escolhido"
  },
  {
   "id": "testes-testar-erro-e-excecao",
   "nome": "Testar erro e exceção",
   "receita": "force a falha da dependência e afirme a mensagem, o código e que nada foi gravado pela metade",
   "prova": "o teste de falha passa e o estado fica consistente"
  },
  {
   "id": "testes-testar-concorrencia",
   "nome": "Testar concorrência",
   "receita": "dispare N chamadas paralelas e afirme o invariante (sem duplicata, saldo correto)",
   "prova": "100 chamadas paralelas mantêm o total certo"
  },
  {
   "id": "testes-testar-upload-e-arquivos",
   "nome": "Testar upload e arquivos",
   "receita": "use arquivos pequenos de verdade, incluindo tipo falso e tamanho acima do limite",
   "prova": "arquivo inválido é recusado com o erro certo"
  },
  {
   "id": "testes-testar-e-mail-e-notificacoes",
   "nome": "Testar e-mail e notificações",
   "receita": "capture o envio num servidor falso (MailHog) e leia o conteúdo e os links",
   "prova": "o e-mail de teste traz o link válido"
  },
  {
   "id": "testes-testar-permissoes",
   "nome": "Testar permissões",
   "receita": "percorra a matriz papel por rota e afirme 200 ou 403",
   "prova": "nenhum papel acessa o que não deveria"
  },
  {
   "id": "testes-testar-migracao",
   "nome": "Testar migração",
   "receita": "aplique do zero, depois de um dump antigo com dados e rode o rollback",
   "prova": "o dado antigo sobrevive à migração"
  },
  {
   "id": "testes-teste-de-acessibilidade-automatico",
   "nome": "Teste de acessibilidade automático",
   "receita": "rode axe no teste de componente e na página, e complete com navegação por teclado",
   "prova": "zero violações graves e o fluxo funciona sem mouse"
  },
  {
   "id": "testes-teste-de-desempenho-pontual",
   "nome": "Teste de desempenho pontual",
   "receita": "meça o tempo ou a alocação da função crítica com orçamento e falhe se passar",
   "prova": "regressão de 20% quebra o teste"
  },
  {
   "id": "testes-dados-de-teste-anonimizados",
   "nome": "Dados de teste anonimizados",
   "receita": "gere sintéticos (faker) ou mascare uma cópia; nunca use dado real de cliente",
   "prova": "nenhum dado pessoal real no repositório de testes"
  },
  {
   "id": "testes-paralelizar-a-suite",
   "nome": "Paralelizar a suíte",
   "receita": "isole portas, banco e arquivos temporários por worker e divida por tempo",
   "prova": "a suíte cai de tempo sem falhas novas"
  },
  {
   "id": "testes-teste-de-componente-isolado",
   "nome": "Teste de componente isolado",
   "receita": "renderize com props e dublês e teste o comportamento visível (Testing Library)",
   "prova": "a refatoração do markup não quebra o teste"
  },
  {
   "id": "testes-teste-de-smoke-pos-deploy",
   "nome": "Teste de smoke pós-deploy",
   "receita": "um script chama saúde, login e uma rota-chave no ambiente real e falha o deploy se algo quebrar",
   "prova": "o deploy de teste passa e o smoke falha se o serviço cair"
  }
 ]
}
