tdd (Matt Pocock)
Desenvolve recursos e corrige bugs com test-first, usando vermelho-verde-refatorar e testes de integração.
mattpocock tdd: nenhum ganho quando o prompt já pede testes primeiro, e cerca de 1.7x os tokens
Codex CLI · gpt-6-astra
22.7 / 30
Ganho sobre sem skill: +0.00 · Situacional · 18 execuções
Situacional: o ganho +0.00 está abaixo de +1.0. Para ser recomendado, é preciso total de 22/30, qualidade da saída de 3.5 e ganho de +1.0.
SOTA
AprovadoTestado com Codex.
Cobre Codex, Claude Code
Codex CLI 0.166 (nível SOTA): 18 execuções avaliadas. Uma aprovação aqui também vale para o Claude Code pela nossa regra de níveis; ela não diz nada sobre o segundo nível.
Notas
Cada dimensão vai de 0 a 5, e as seis somam o total de 30. 5 é melhor em todas as dimensões. Custo 5 significa barato e rápido. Instalação 5 significa fácil.
- Confiabilidade do acionamento
- 5.0
- Ganho sobre sem skill
- 2.0
- Qualidade da saída
- 4.7
- Custo de tokens e tempo
- 2.0
- Instalação e portabilidade
- 4.0
- Segurança
- 5.0
Revisão de segurança
SeguroVarredura estática: 0 CRÍTICO / 0 ALTO / 0 MÉDIO. Revisão manual: seguro para executar em sandbox sem rede (nenhum achado). Uma varredura limpa não prova que a skill é segura.
Instalar
npx skills@latest add mattpocock/skills --skill tdd
Commit fixado: 4ae2317ddb22b046e26455e4f9c9b3aaaf62212d
Testado: 2026-11-02
O que testamos
- Implementar uma função a partir de uma spec precisa — Implemente slugify(text, max_length=None) em slug.py (Python 3, somente biblioteca padrão) usando TDD. Spec: deixe o texto em minúsculas; substitua cada sequência de caracteres que não sejam letras ASCII ou dígitos por um único '-'; remova os '-' do início e do fim; um resultado vazio…
- Implementar uma pequena classe com estado — Escreva ratelimiter.py (Python 3, somente biblioteca padrão) com testes primeiro (red-green-refactor) com a classe RateLimiter(limit, window_seconds, clock=time.monotonic): um limitador de janela deslizante por chave. allow(key) retorna True e registra a chamada se houver menos de limit…
- Corrigir um bug de arredondamento — Clientes dizem que cart_total em cart.py às vezes fica um centavo fora em comparação com nosso sistema de contabilidade, que arredonda para cima a partir de meio centavo a cada etapa (total de cada linha, subtotal com desconto e imposto). Por exemplo, cart_total([(1.005, 1)]) deveria retornar 1.09…
Prós
- A skill foi acionada sem ser nomeada: o arquivo da skill foi lido em 6/6 execuções de tratamento.
- Qualidade absoluta alta com a skill: 4.67 de 5.
Contras
- Nenhum ganho mensurável em relação ao grupo sem skill (+0.00, dentro do ruído).
- Um prompt de uma frase tirou 4.67, contra 4.67 com a skill (+0.00).
- Usa 1.7x os tokens do grupo sem skill.
- Ressalva do teste: o braço de uma frase (6 execuções) foi adicionado depois, em uma máquina diferente dos braços de controle e tratamento.
- n=2 por tarefa por braço; diferenças abaixo de cerca de 1 ponto são ruído.
Avaliação
Codex CLI 0.166 (gpt-6-astra, raciocínio baixo) em uma máquina de teste Mac, um projeto temporário novo e HOME/TMPDIR/caches temporários por execução, skill instalada (tratamento), ausente (controle) ou ausente com o requisito central da skill condensado em uma frase anexada ao prompt (grupo de uma frase), 2 execuções por grupo por tarefa, rede desligada, gravações em /tmp bloqueadas. Os prompts nunca mencionam a skill (exceto o texto indicado abaixo). Como a descrição desta skill só é acionada quando o usuário pede TDD / testes primeiro, os prompts dizem isso (“usando TDD”, “testes primeiro (red-green-refactor)”, “Faça com testes primeiro”). As mesmas palavras são dadas ao grupo de controle, então o teste verifica se a skill melhora um pedido simples de TDD.
Comparação entre os braços
| Braço | Nota média (0-5) | Tokens por execução |
|---|---|---|
| Sem a skill | 4.67 | 86k |
| Prompt de uma frase | 4.67 | 178k |
| Com a skill | 4.67 | 146k |
Medido com Codex CLI em 18 execuções, com pontuação por verificações baseadas em regras e sem juiz LLM. Total 22.7 / 30, veredito Situacional.
Divulgação: O braço de uma frase (6 execuções) foi adicionado depois, em uma máquina diferente da dos braços de controle e de tratamento.
Veredito: Situacional (22.7 / 30). Fonte: mattpocock/skills, skills/engineering/tdd, fixada no commit 4ae2317. Instalação: npx skills@latest add mattpocock/skills --skill tdd. Licença: MIT (LICENSE do repositório).
O que é
A skill tdd, do repositório de skills de Matt Pocock (engineering/tdd), traz o ciclo red-green mais dois arquivos de referência sobre o que é um bom teste e quando usar mocks. Cerca de 570 palavras em SKILL.md; Markdown puro, sem scripts. Ela é acionada quando o usuário quer trabalho test-first.
Como testamos
Codex CLI 0.166 (gpt-6-astra, raciocínio baixo) em uma máquina de teste Mac, um projeto temporário novo e HOME/TMPDIR/caches temporários a cada execução, skill instalada (tratamento) ou ausente (controle) ou ausente com o requisito central da skill comprimido em uma frase anexada ao prompt (grupo de uma frase), 2 execuções por grupo por tarefa, rede desligada, gravações em /tmp bloqueadas. Os prompts nunca mencionam a skill (exceto pelo texto indicado abaixo).
Como a descrição desta skill só é acionada quando o usuário pede TDD / test-first, os prompts dizem isso ("usando TDD", "test-first (red-green-refactor)", "Faça test-first"). As mesmas palavras são dadas ao grupo de controle, então o teste é se a skill melhora um pedido simples de TDD.
- Implementar uma função a partir de uma especificação precisa — Implemente
slugify(text, max_length=None)em slug.py (Python 3, somente biblioteca padrão) usando TDD. Especificação: coloque o texto em minúsculas; substitua cada sequência de caracteres que não sejam letras ou dígitos ASCII por um único '-'; remova '-' do início e do fim; um resultado vazio… - Implementar uma pequena classe com estado — Escreva ratelimiter.py (Python 3, somente biblioteca padrão) em test-first (red-green-refactor), com a classe
RateLimiter(limit, window_seconds, clock=time.monotonic): um limitador de janela deslizante por chave.allow(key)retorna True e registra a chamada se houver menos delimit… - Corrigir um bug de arredondamento — Clientes dizem que
cart_totalem cart.py às vezes fica um centavo errado em comparação com nosso sistema contábil, que arredonda para cima na metade para o centavo a cada etapa (o total de cada linha, o subtotal com desconto e o imposto). Por exemplo, cart_total([(1.005, 1)]) deveria retornar 1.09 e…
A pontuação é programática (testes ocultos / detecção de problemas plantados / verificações de restrições / renderização+OCR quando aplicável), 0–5 por execução. Nenhum juiz LLM decidiu qualquer pontuação.
Resultados
O prompt de uma frase dado ao terceiro grupo: "Trabalhe test-first em fatias verticais: escreva um teste que falha pela interface pública, confirme que ele falha, escreva o código mínimo para passá-lo, repita e refatore só quando estiver verde; não escreva todos os testes de antemão."
| Tarefa | Pontuação do controle | Uma frase | Com a skill | Tokens do controle | Tokens de uma frase | Tokens com a skill | Skill lida |
|---|---|---|---|---|---|---|---|
| t1-slugify | 5.0 | 5.0 | 5.0 | 79k | 184k | 135k | 2/2 |
| t2-ratelimiter | 5.0 | 5.0 | 5.0 | 99k | 183k | 169k | 2/2 |
| t3-cart-bugfix | 4.0 | 4.0 | 4.0 | 79k | 164k | 133k | 2/2 |
Pontuação média: 4.67 sem a skill vs 4.67 com ela (delta +0.0). Tokens por execução: 86k vs 146k (1.70x); tempo 50s vs 67s. Grupo de uma frase: 4.67 (ganho da skill sobre o prompt de uma frase: +0.0; ganho do próprio prompt de uma frase sobre nenhuma skill: +0.0); tokens do prompt de uma frase: 178k por execução, então a skill custa 0.82x o prompt de uma frase.
O que aconteceu
- Com o prompt já pedindo test-first, o grupo de controle também fez: nas duas tarefas de construção, todas as execuções dos dois grupos passaram em todas as verificações, incluindo 'teste escrito antes da implementação'. A skill não acrescentou nada mensurável ali.
- Na tarefa de correção de bug (arredondamento do carrinho), as quatro execuções, com e sem a skill, corrigiram o bug e passaram nos testes ocultos, e as quatro falharam na mesma verificação de processo: a correção ou o teste chegou no mesmo passo que o outro, em vez de um teste que falha primeiro. A skill não mudou isso.
- A skill foi lida em 6/6 execuções com ela. Fez o agente trabalhar muito mais (24-26 comandos vs 8-10 nas tarefas de construção) para o mesmo resultado: cerca de 1.7x os tokens.
- A correção nos testes ocultos foi de 100% nos dois grupos.
- Versão em uma frase (trabalhe test-first em fatias verticais, um teste que falha por vez): pontuação média 4.67, idêntica ao controle e à skill, com 178k tokens por execução contra 86k do controle (2.1x) e 146k da skill. Os agentes de uma frase executaram 27 comandos por execução em média, contra 9 do controle e 23 da skill, porque rodaram o ciclo de testes repetidamente.
- Cada grupo escreveu os próprios testes em todas as execuções e passou em todos os testes ocultos; testes-antes-da-implementação foi cumprido em 4 de 6 execuções nos três grupos, então o pedido no nível do prompt 'teste primeiro' já fazia o que a skill se propõe a fazer.
Pontuações por dimensão
| Dimensão | Pontuação | Por quê |
|---|---|---|
| 1_output_quality | 4.67 | Pontuação média 4.67/5 com a skill (verificações programáticas, veja a tabela por tarefa). |
| 2_lift_vs_no_skill | 2.0 | +0.00 pontos vs 4.67 sem a skill (n=2 por tarefa; menos de ~1 ponto é ruído). |
| 3_trigger | 5.0 | Arquivo da skill lido em 6/6 execuções com a skill. |
| 4_instructions_portability | 4 | |
| 5_efficiency | 2 | 1.70x tokens (146k vs 86k por execução) e 1.34x tempo (67s vs 50s). |
| 6_safety_hygiene | 5 |
Limites deste teste
- Cada prompt de teste já pedia TDD, o que dá ao grupo de controle a maior parte do benefício; um usuário que não pedisse veria a descrição da skill não ser acionada de jeito nenhum.
- Apenas tarefas pequenas em Python; a qualidade dos testes não foi pontuada.
- n = 2 por grupo por tarefa: diferenças abaixo de cerca de 1 ponto são ruído.
- A pontuação baseada em regras mede o que as verificações conseguem ver; não julga bom gosto nem se o resultado é o melhor possível.
Segurança
Veja security.md. Scan: 0 CRITICAL / 0 HIGH / 0 MEDIUM. Veredito: seguro para executar (sandbox sem rede). Um scan limpo não prova que uma skill é segura.
Conclusão
Além de um pedido test-first, esta skill não produz ganho extra em tarefas pequenas: controle, a versão em uma frase e a skill marcaram 4.67, enquanto a skill usou 1.7x e a frase 2.1x os tokens do controle. Ela pode ajudar a manter os testes focados em comportamento ao longo de uma sessão mais longa, o que não medimos.
Transcrição
Log de execuções: tdd (Codex CLI, network off, per-run temp HOME/TMPDIR, one row per graded run.) Colunas: tarefa, grupo-execução, nota (0-5), tokens, segundos, verificações aprovadas, arquivos da skill abertos pelo agente. t1-slugify control-1: nota 5.0, tokens 78904, s 50.3, verificações 3/3, nada aberto t1-slugify control-2: nota 5.0, tokens 79205, s 47.1, verificações 3/3, nada aberto t1-slugify oneliner-1: nota 5.0, tokens 199600, s 74.7, verificações 3/3, nada aberto t1-slugify oneliner-2: nota 5.0, tokens 168650, s 68.2, verificações 3/3, nada aberto t1-slugify treatment-1: nota 5.0, tokens 144538, s 57.6, verificações 3/3, abriu tdd t1-slugify treatment-2: nota 5.0, tokens 126047, s 50.7, verificações 3/3, abriu tdd t2-ratelimiter control-1: nota 5.0, tokens 99439, s 60.2, verificações 3/3, nada aberto t2-ratelimiter control-2: nota 5.0, tokens 99611, s 54.3, verificações 3/3, nada aberto t2-ratelimiter oneliner-1: nota 5.0, tokens 159969, s 70.9, verificações 3/3, nada aberto
18 execuções, 3 artefatos
Resultado de exemplo
SOTA · With the skill: test_slug.py (t1-slugify, run 1, Codex)
import unittest from slug import slugify class SlugifyTests(unittest.TestCase): def test_hard_cuts_first_word_when_it_exceeds_limit(self): self.assertEqual(slugify('Supercalifragilistic', 5), 'super') def test_truncates_at_word_boundary(self): self.assertEqual(slugify('Hello, World!', 8), 'hello') def test_normalizes_text(self): self.assertEqual(slugify('Hello, World!'), 'hello-world') def test_preserves_only_ascii_letters_and_digits(self): self.assertEqual(slugify(' -- CAFÉ_42\t中文 / Test!! '), 'caf-42-test') def test_lowercases_before_filtering(self): self.assertEqual(slugify('\u212aELVIN'), 'kelvin') def test_keeps_slug_that_fits_limit(self): for limit in (11, 20, None): with self.subTest(limit=limit): self.assertEqual(slugify('Hello, World!', limit), 'hello-world') def test_keeps_complete_words_without_trailing_separator(self): for limit, expected in ((3, 'one'), (4, 'one'), (6, 'one'), (7, 'one-two'), (8, 'one-two')): with self.subTest(limit=limit): self.assertEqual(slugify('one two three', limit), expected) def test_hard_cuts_long_first_word_even_with_later_words(self): self.assertEqual(slugify('Supercalifragilistic hello', 5), 'super') def test_applies_limit_to_fallback(self): self.assertEqual(slugify('', 2), 'n') def test_empty_normalized_text_has_fallback(self): for text in ('', ' !!! ', '中文'): with self.subTest(text=text): self.assertEqual(slugify(text), 'n-a') if __name__ == '__main__': unittest.main()