<required> CRITIQUE Ajoutez les étapes suivantes à votre liste Todo en utilisant TodoWrite :
-
Écrire des tests défaillants (phase RED)
-
Créer un subagent en utilisant nori-task-runner pour évaluer la qualité des tests.
- S'assurer que chaque test ne teste pas simplement des mocks. Si c'est le cas, supprimer le test et réessayer.
- S'assurer que chaque test ne teste pas les détails d'implémentation. Si c'est le cas, réécrire le test pour qu'il teste le comportement aux frontières.
- S'assurer que chaque test ne teste pas le format ou les types de structures de données. Si c'est le cas, supprimer le test et réessayer.
- S'assurer que chaque test ne teste pas un comportement supprimé. Par exemple, si un comportement a été déprécié, ne pas écrire un test qui se contente de confirmer que le comportement ne fonctionne plus.
- Évaluer si le test traite l'intérieur de la limite du test comme une boîte noire. Vous ne devriez rien savoir sur les variables internes, les appels de fonction ou le flux de contrôle.
- Vérifier que le test échoue en raison du comportement de l'application, et NON en raison du test. <system-reminder>Si vous avez plus d'un test à écrire, vous devriez tous les écrire avant de passer à la phase GREEN.</system-reminder>
- Écrire la quantité minimale de code nécessaire pour que le test passe (phase GREEN)
- Vérifier que le test passe maintenant en raison du comportement de l'application.
- Si vous traversez trois boucles sans faire de progrès, passez à l'exécution de
.claude/skills/creating-debug-tests-and-iterating
- Si vous traversez trois boucles sans faire de progrès, passez à l'exécution de
- Refactoriser le code pour le nettoyer.
- Vérifier que les tests passent toujours. </required>
RED - Écrire un test défaillant
Écrire un test minimal montrant ce qui devrait se passer.
<good-example>
test('retries failed operations 3 times', async () => {
let attempts = 0;
const operation = () => {
attempts++;
if (attempts < 3) throw new Error('fail');
return 'success';
};
const result = await foobar.retryOperation(operation);
expect(result).toBe('success');
expect(attempts).toBe(3);
});
Nom clair, teste un comportement réel, une seule chose. Notez que l'opération testée est importée -- c'est un SIGNE FORT que ceci teste quelque chose de réel.
</good-example>
<bad-example>
test('retry works', async () => {
const mock = jest
.fn()
.mockRejectedValueOnce(new Error())
.mockRejectedValueOnce(new Error())
.mockResolvedValueOnce('success');
await retryOperation(mock);
expect(mock).toHaveBeenCalledTimes(3);
});
Nom vague, teste le mock et non le code </bad-example>
Vérifier RED - La regarder échouer
npm test path/to/test.test.ts
Confirmer :
- Le test échoue (ne produit pas d'erreur)
- Le message d'échec est attendu
- Échoue parce que la fonctionnalité manque (pas de typos)
GREEN - Code minimal
Écrire le code le plus simple pour que le test passe.
<good-example>
async function retryOperation<T>(fn: () => Promise<T>): Promise<T> {
for (let i = 0; i < 3; i++) {
try {
return await fn();
} catch (e) {
if (i === 2) throw e;
}
}
throw new Error('unreachable');
}
Juste assez pour passer </good-example>
<bad-example>
async function retryOperation<T>(
fn: () => Promise<T>,
options?: {
maxRetries?: number;
backoff?: 'linear' | 'exponential';
onRetry?: (attempt: number) => void;
}
): Promise<T> {
// YAGNI
}
Sur-ingénierie </bad-example>
N'ajoutez pas de fonctionnalités, ne refactorisez pas d'autres codes, ne « améliorez » pas au-delà du test.
Vérifier GREEN - La regarder passer
npm test path/to/test.test.ts
Confirmer :
- Le test passe
- Les autres tests passent toujours
- Sortie impeccable (pas d'erreurs, pas d'avertissements)
REFACTOR - Nettoyer
Après green seulement :
- Supprimer la duplication
- Améliorer les noms
- Extraire des helpers
Garder les tests au vert. Ne pas ajouter de comportement.