15 KiB
Impl: Skills e docs: codificar a pirâmide de testes (unit primeiro, int depois, E2E só com benefício real por fluxo)
Status: rascunho Atualizado em: 2026-08-24 Issue: #838 Intenção: docs/plans/ops90-skills-piramide-testes.md Appetite restante: herdado (~0,5–1 dia eng; um outcome verificável — sem corte)
Leitura da intenção
- Outcome: Ao planejar qualquer entrega, a decisão de nível de teste é orientada pela ordem unit→int→e2e-com-benefício, e a política OPS72 continua a valer intacta.
- O que NÃO negociar: política OPS72 intacta (gate local discricionário, CI/PR blast radius
selected, full só noverifydo deploy); nenhuma regra de % de cobertura; nenhuma proibição de e2e; sem mudança de gate nem de CI; sem migration/schema/UI; anti-goal de rewrite massivo de skills e de "cartilha de boas práticas" genérica. - O que reavaliar: a hipótese de que todos os candidatos da intenção precisam de mudança —
ci-cd-and-automation(é skill genérica de repo, exemplo),engineering-audit(varretests/, avalia por classes) eagent-work-issue(só delega ao pipeline) podem ficar de fora;AGENTS.md/AGENTS-infra.mdsó recebem a pirâmide se houver linha curta natural (achado: são densas e só de gate — provável ação nenhuma).
Abordagem recomendada
flowchart LR
P[Planejar entrega] --> Q1{Lógica pura, sem I/O?}
Q1 -->|sim| U[unit - tests/unit - DATABASE_URL inválida]
Q1 -->|não| Q2{Cruza fronteira Payload/DB/API?}
Q2 -->|sim| I[int - tests/int - Payload real em teqo_test]
Q2 -->|não| Q3{Fluxo crítico / UX / contrato de URL?}
Q3 -->|sim| E[e2e - tests/e2e - Playwright smoke - benefício real]
Q3 -->|não| Z["unit onde couber; sem teste novo sem valor"]
U --> POL[OPS72: local discricionário - CI selected - full só no verify]
I --> POL
E --> POL
Z --> POL
Opções consideradas: A — editar todos os candidatos da intenção ("harmonizar") | B — edição cirúrgica só onde há lacuna real (~6 arquivos + 2 docs), com test-driven-development como dono canônico | C — criar documento canônico novo (ex. docs/TESTING-PYRAMID.md) e apontar tudo para ele
Recomendação: B — porque atende os anti-goals (mudança mínima, sem documento novo, edit-the-owner), casa com a questão em aberto resolvida na intenção (opção A: TDD skill como dono da definição, docs/TESTING.md como referência operacional) e evita o DRY de docs com OPS72 já detalhada em AGENTS-infra.md L21 e execution-pipeline.md §E2E.
Rejeitadas: A porque é o rabbit hole "harmonizar skills consistentes" — agent-work-issue, ci-cd-and-automation e engineering-audit não têm lacuna real, e mexer em skill genérica viola "edit the owner, don't twin"; C porque a intenção cortou explicitamente "sem novo documento canônico" e duplicaria a definição ao lado do dono natural.
Decisões não triviais secundárias (formato Opções | Recomendação | Rejeitadas):
- Onde a preferência de nível mora no fluxo de execução — Opções: A
work-issue/SKILL.mdPasso 4 | Bexecution-pipeline.md§Executar | C ambos. Recomendação: B+C-leve — a pipeline é compartilhada porwork-issueeagent-work-issue(que delega), então a frase lá cobre as duas skills de uma vez (DRY); o Passo 4 recebe só uma cláusula curta apontando para a pipeline. Rejeitadas: A puro porque deixa oagent-work-issuede fora do enunciado sem justificativa. AGENTS.md/AGENTS-infra.mdrecebem a pirâmide? — Opções: A editar linha de testes | B não editar. Recomendação: B — as linhas existentes são só gate/política OPS72 (L14/L21) e estão densas; a preferência já fica a um passo (pipeline +docs/TESTING.md); intenção autoriza ação nenhuma. Rejeitada: A porque empurra contexto de skill para o topo de AGENTS, o oposto da direção deste item.browser-testing-with-devtools— Opções: A apenas rótulo de uma linha | B reescrever seções para "vender" a pirâmide. Recomendação: A — uma linha no intro/anti-pattern table reconhecendo browser check como caso legítimo de "e2e com benefício real"; a tabela L287 já racionaliza "Unit tests don't test CSS, layout, or real browser rendering". Rejeitada: B porque a skill é uma ferramenta de debug, não de estratégia de teste.
Componentes / mudanças
Edições propostas por arquivo (textos curtos; copy pt-BR nos arquivos do repo, inglês nas skills genéricas):
-
.agents/skills/test-driven-development/SKILL.md— dono canônico da pirâmide. Inserir um bloco novo no FIM da seção The Test Pyramid (após L186, antes de## Writing Good Tests) — posição que preserva os ranges de linha citados na intenção (§144–186):### This repo: the three layers (unit → int → e2e) In this repo the pyramid maps to `tests/` (see `docs/TESTING.md` and the `codebase-map` rule): | Level | Where | Runs against | | ------------ | ------------------------------ | --------------------------------------------------------------------- | | Unit (~most) | `tests/unit/**/*.unit.spec.ts` | deliberately invalid `DATABASE_URL` — pure logic, no DB | | Integration | `tests/int/**/*.int.spec.ts` | real Payload + Postgres `teqo_test` | | E2E (few) | `tests/e2e` (Playwright smoke) | only when the flow has real benefit (critical path, UX, URL contract) | E2E policy (OPS72): local is discretionary, PR CI runs only the affected surface (`selected`), full only in the deploy `verify` job — the PR never runs full e2e.Justificativa: âncora exigida pelo aceite ("sem recriar a definição do zero") — a definição genérica (§144–186) fica intocada; o bloco só mapeia para as camadas
tests/e aponta OPS72 sem copiar o corpo da política. -
.agents/rules/codebase-map.mdc(L26) — reescrever a linhatests/para explicitar a ordem:- `tests/` — `unit` primeiro (lógica pura, DATABASE_URL inválida), `int` para fronteiras Payload/DB (Payload real em `teqo_test`, fixtures em `tests/helpers/campaignFixtures.ts`), `e2e` só com benefício real por fluxo (Playwright smoke).Justificativa: aceite pede que a linha das 3 camadas do mapa explicite a ordem; é a linha que todo agente lê ao navegar o codebase.
-
docs/TESTING.md(após L9, antes do parágrafo CI) — um parágrafo de preferência, sem tocar no corpo OPS72:**Preferência de nível (pirâmide):** unit primeiro (lógica pura) → int para fronteiras Payload/DB → e2e somente quando o fluxo tem benefício real que as camadas inferiores não cobrem (fluxo crítico de usuário, UX/navegação, contrato de URL). E2E fica smoke; a maioria do comportamento de campanha é pinado em int.Justificativa:
docs/TESTING.mdé a referência operacional (decisão da intenção); a ordem hoje é implícita, o parágrafo a torna explícita sem editar a política. -
.agents/skills/work-issue/execution-pipeline.md(§Executar, L7–19) — linha de preferência antes do item 1 da ordem (a seção §E2E local afetado L24–49 não é tocada):**Nível de teste:** unit primeiro (lógica pura, `tests/unit`) → int para fronteiras Payload/DB (`tests/int`) → e2e só com benefício real por fluxo (`tests/e2e`); dono da definição: `test-driven-development`.Justificativa: a pipeline é compartilhada por
work-issueeagent-work-issue— uma frase cobre as duas skills de execução (decisão B+C-leve). -
.agents/skills/work-issue/SKILL.md(Passo 4, L141) — estender o bullet existente com uma cláusula curta:- **Nível de teste:** unit → int → e2e-com-benefício (ver pipeline); **E2E local afetado (OPS72):** discricionário — rode os e2e criados + mesma superfície.Justificativa: enuncia a preferência ao lado da política OPS72 já documentada (aceite), sem duplicar a definição.
-
.agents/skills/code-review-and-quality/SKILL.md— duas adições mínimas:- Step 2 "Review the Tests First" (L152–161), um bullet novo:
- Is the test level right for the change? (unit → int → e2e-com-benefício — e2e only when the flow has real benefit the lower layers don't cover) - Checklist final (L314): estender
- [ ] Tests cover the change adequately→- [ ] Tests cover the change adequately at the right level (unit → int → e2e-com-benefício)Justificativa: aceite pede que a revisão valide o nível escolhido; é o encaixe natural do fluxo desejado da intenção.
- Step 2 "Review the Tests First" (L152–161), um bullet novo:
-
.agents/skills/improve-code-quality/SKILL.md(L269, exit checklist) — estender o bullet existente (que já exige testes sem DB — ou seja, unit-first implícito):- [ ] Business rules have tests that run with no database or framework (unit — first level of the pyramid); Payload/DB boundaries go to `tests/int`, e2e only with real benefit (TESTING.md Safety Net Map complete for changed modules).Justificativa: transforma o viés unit-first já presente em preferência explícita de níveis.
-
.agents/skills/browser-testing-with-devtools/SKILL.md(intro L20 ou tabela L287) — uma linha de rótulo:Browser verification is a legitimate "e2e with real benefit" case: unit and integration tests don't cover CSS, layout, or real rendering (test pyramid: unit → int → e2e — see `test-driven-development`).Justificativa: resolve a questão em aberto da intenção (rótulo explícito) sem mudar o corpo da skill.
-
Sem mudança (confirmar apenas, sem diff):
agent-work-issue/SKILL.md(só delegação — a edição da pipeline o cobre),ci-cd-and-automation/SKILL.md(diagrama genérico é exemplo, não regra do repo — mexer violaria "edit the owner, don't twin"),engineering-audit/SKILL.md(avaliação por classes; sem gap de nível),AGENTS.md/AGENTS-infra.md(linhas de gate/OPS72 apenas — decisão B acima).
- Migration: sem migration (docs/skills não tocam schema)
- Access / Consent: N/A — nenhum path de escrita em collections
- UI: N/A — Impeccable A; sem UI
Dados → forma (se aplicável)
N/A — meta-chore de guias; sem dados de produto.
Fases verificáveis
- TDD skill + docs de teste (~30% do appetite) — bloco Teqo no fim de The Test Pyramid; reescrever L26 do
codebase-map.mdc; parágrafo de preferência emdocs/TESTING.md. Verificar:git diffmostra apenas inserções (seções §144–186 intactas, bloco novo só após L186); corpo OPS72 dedocs/TESTING.mdinalterado. - Pipeline e work-issue (~25%) — linha de preferência no §Executar do
execution-pipeline.md; cláusula no Passo 4 dowork-issue/SKILL.md. Verificar: seção §E2E local afetado byte-idêntica no diff;agent-work-issuecontinua delegando sem contradição. - Checklists de revisão + browser (~25%) — bullets em
code-review-and-quality(Step 2 + checklist),improve-code-quality(exit checklist) e linha de rótulo embrowser-testing-with-devtools. Verificar: frases leem bem no contexto; nenhum comando novo introduzido. - Gates e push (~20%) —
tsc --noEmit,pnpm lint(0 warnings),pnpm format:check,pnpm test(guardsopencodeCommands.unit.spec.ts/agentPoolPrompt.unit.spec.tsvarrem.agents/skillspor nome — devem seguir verdes),pnpm build. Commit incluindo oops90-skills-piramide-testes-impl.md; entrega compnpm push.
Rabbit holes / Não escopo (engenharia)
- Rewrite da TDD skill genérica (398 linhas) para "trazer Teqo para dentro" de cada seção — fora; a edição é um bloco novo de ~10 linhas no fim da seção da pirâmide.
- "Harmonizar" skills consistentes (
agent-work-issue,ci-cd-and-automation,engineering-audit,AGENTS*.md) — fora; sem lacuna real, ação mínima ou nenhuma. - Novo documento canônico de testes (ex.
docs/TESTING-PYRAMID.md) — fora; corte explícito da intenção. - Regras de % de cobertura ou proibição de e2e — fora; guardrail da intenção.
- Guards que vigiem conteúdo de skill — fora; decisão da intenção (e acoplaria por conteúdo, quebrando o modelo nome→comando).
- OPS87/OPS88 (engineering e2e/CI) — itens separados, não sobrepostos.
- Reformatar/renomear seções existentes das skills (churn de diff sem valor) — fora; só inserções.
Riscos e mitigação
- DRY de docs (OPS72 já detalhada em
AGENTS-infra.mdL21 eexecution-pipeline.mdL24–49): novos textos apontam para a política, nunca copiam o corpo;docs/TESTING.mdé a referência operacional única. Mitigação: diff-check nas fases 1–2 exigindo seções OPS72 intactas. - Números de linha voláteis (intenção cita §144–186): inserção no fim da seção preserva os ranges existentes. Mitigação: posição do bloco fixada após L186; verificar com diff na fase 1.
- Guards de prompt (
opencodeCommands/agentPoolPrompt) varrem.agents/skillspor nome: edição de texto não quebra; comando/skill novo quebra. Mitigação: nenhum comando novo;pnpm testna fase 4. - Concorrência com OPS87/OPS88 (skills de teste/CI podem ser editadas por eles): worktrees por item; se conflitar no rebase, re-aplicar só os trechos-alvo deste plano.
- Deriva para "cartilha": revisores podem sugerir expandir. Mitigação: escopo fixado na lista de arquivos acima; o aceite da intenção exige mudança mínima — qualquer expansão é corte.
- Quebra acidental de OPS72 ao editar
work-issue: Mitigação: edição por cláusula aditiva (nunca reescrita de bullet) + diff-check da fase 2 + checklist de aceite.
Aceite de engenharia
- Aceite de produto da intenção coberto: TDD skill ancorada ao Teqo (camadas
tests/+ OPS72);work-issueecode-review-and-qualityenunciam a preferência de nível;docs/TESTING.mdecodebase-map.mdcexplicitam a ordem unit→int→e2e-com-benefício; nenhuma regra de % de cobertura; nenhuma proibição de e2e. - Política OPS72 intacta — gate local discricionário, CI
selected, full só noverifydo deploy — verificada por diff nas fases 1–2 (seções OPS72 deexecution-pipeline.md,docs/TESTING.md,AGENTS-infra.mdinalteradas). - Invariantes AGENTS/engineering-standards: edição cirúrgica dos donos; copy pt-BR nos arquivos do repo e inglês nas skills genéricas; sem migration/schema/UI;
*-impl.mdcommitado na entrega. - Guards verdes:
pnpm testpassa (opencodeCommands/agentPoolPromptsem novos nomes de comando/skill). - Gates:
tsc --noEmit,pnpm lint(0 warnings),pnpm format:check,pnpm buildverdes. - Nenhum documento canônico novo, nenhum guard novo, nenhuma mudança de gate/CI.
Self-score decision-quality: 4/5 — decisões caras com rejeitadas (escopo da edição, local da preferência, AGENTS sem mudança); abordagem cabe no appetite (~0,5–1 dia em 4 fases); rabbit holes nomeados; depth check reusa donos existentes (TDD skill como âncora, pipeline compartilhada cobre agent-work-issue, sem duplicar OPS72); aceite de produto intacto.