rtk-tdd

Par rtk-ai · rtk

Applique le TDD (Red-Green-Refactor) pour le développement Rust. Se déclenche automatiquement sur les tâches d'implémentation, de test, de refactoring et de correction de bugs. Fournit des patterns de test idiomatiques Rust avec anyhow/thiserror, cfg(test) et le workflow Arrange-Act-Assert.

npx skills add https://github.com/rtk-ai/rtk --skill rtk-tdd

Workflow TDD en Rust

Trois Lois du TDD

  1. N'écris PAS de code production sans un test défaillant
  2. Écris seulement assez de test pour échouer (y compris les erreurs de compilation)
  3. Écris seulement assez de code production pour passer le test défaillant

Cycle : RED (test échoue) -> GREEN (minimum pour passer) -> REFACTOR (nettoyage, cargo test)

Étapes Red-Green-Refactor

1. Écris le test dans #[cfg(test)] mod tests du MÊME fichier
2. cargo test MODULE::tests::test_name  -- doit ÉCHOUER (red)
3. Implémente le minimum dans la fonction
4. cargo test MODULE::tests::test_name  -- doit RÉUSSIR (green)
5. Refactorise si nécessaire, relance cargo test (toujours green)
6. cargo fmt && cargo clippy --all-targets && cargo test  (portail final)

Ne saute jamais l'étape 2. Si le test passe immédiatement, il ne teste rien.

Patterns de Tests Idiomatiques en Rust

Pattern Utilisation Quand
Arrange-Act-Assert Structure de base pour chaque test Toujours
assert_eq! / assert! Comparaison directe / booléens Valeurs déterministes
assert!(result.is_err()) Test du chemin d'erreur Entrées invalides
Result<()> type de retour Tests avec opérateur ? Fonctions défaillibles
#[should_panic] Panique attendue Invariants, préconditions
tempfile::NamedTempFile Tests fichier/I/O Code dépendant du système de fichiers

Patterns par Type de Code

Type de Code Pattern de Test Exemple
Fonction pure (str -> str) Littéral d'entrée -> assert sortie assert_eq!(truncate("hello", 3), "...")
Parsing/filtrage Chaîne brute -> filtrer -> contains/not-contains assert!(filter(raw).contains("expected"))
Validation/sécurité Entrées limites -> assert booléen assert!(!is_valid("../etc/passwd"))
Gestion d'erreur Mauvaise entrée -> is_err() assert!(parse("garbage").is_err())
Roundtrip struct/enum Construire -> sérialiser -> désérialiser -> égal assert_eq!(from_str(to_str(x)), x)

Convention de Nommage

test_{fonction}_{scenario}
test_{fonction}_{type_entree}

Exemples : test_truncate_edge_case, test_parse_invalid_input, test_filter_empty_string

Quand NE PAS utiliser le TDD pur

  • Fonctions appelant Command::new() -> teste le parser, pas l'exécution
  • std::process::exit() -> refactorise en Result d'abord, puis teste le Result
  • I/O direct (SQLite, réseau) -> utilise tempfile/mock ou teste la logique pure séparément
  • Wiring main/CLI -> couvert par les tests d'intégration/smoke tests

Portail Pré-Commit

cargo fmt --all --check
cargo clippy --all-targets
cargo test

Les 3 doivent passer. Aucune exception. Aucun #[allow(...)] sans justification documentée.

Skills similaires