Test Driven Development avec Ruby on Rails
Matt Moore a récemment publié une checklist permettant de vérifier la qualité de son code rails. La plupart des développeurs la liront avec satisfaction en se disant : “la séparation de la logique et des vues, c’est bon… La simplification des requêtes à la db, c’est fait… Le maintient de la simplicité des contrôleurs, bien entendu…”. Puis vient la question des tests. “Ah oui, euh… boaf”.
Il y a plusieurs raisons qui causent la désaffection des outils de tests de ruby on rails :
- C’est un ensemble de méthodes nouvelles à prendre en mains. Ces méthodes ne sont jamais utilisées dans une application normale et il faut donc d’abord s’y familiariser.
- Dans une première approche, ces outils semblent particulièrement mal documentés.
- On ne voit pas l’intérêt de perdre du temps à écrire une batterie de test alors qu’on vient de tester manuellement son code au fur et à mesure qu’on l’écrivait. C’est tout sauf “DRY“-ant ou agile.
Cette dernière raison est particulièrement défendable et on en vient vite à se demander comment David Heinemeier Hansson peut à la fois répéter si souvent qu’il faut écrire des tests et en même temps souscrire aux recommandation du getting real.
Quand dois-je écrire mes tests?
C’est en effet des différentes réponses à cette question que vient le malentendu. Deux choix courants conduisent à rapidement négliger les tests :
- Écrire ses tests lorsqu’on a terminé son modèle ou son contrôleur.
- Écrire ses tests après avoir fini d’écrire une méthode.
Le premier choix décourage vite en face du laborieux travail à exécuter, qui se montre parfois plus conséquent que l’écriture première du code, particulièrement si on ne fait pas une application à base de CRUD. Le second choix est plus flexible, mais on se voit obligé de revenir souvent dans le code des tests parce qu’à l’écriture de la méthode suivante, on se rend compte qu’il faut finalement modifier un peu la précédente.
Il y a heureusement une troisième option, et c’est celle qui constitue le sujet de ce billet : le développement piloté par tests.
Le développement piloté par tests inverse radicalement la conception que nous avons des tests. Au lieu de les écrire a posteriori lorsque nous avons terminé un pan de code, il nous conseille d’écrire les tests préalablement à tout code.
Quel intérêt?
L’idée de tester du code qui n’existe pas encore peut paraître étrange, mais c’est pourtant une technique puissante de développement agile et solide.
Lorsque vous vous lancez dans l’écriture de votre code, vous devez déjà avoir une idée des différents éléments qui vont composer votre application et de la manière dont ils vont se comporter. Je ne parle bien sûr pas des nouvelles fonctionnalités qui viendront étendre votre application par la suite lorsque le besoin s’en fera ressentir, mais de la stricte base : mon application contient des User, des Article et des Comment ; chacun doit pouvoir être créé, montré, modifié et effacé, les Article doivent être rattachés à un User et les Comment à un Article. Rajoutez à cela les quelques fonctionnalités particulières à votre application.
Vous pouvez écrire ce design original dans un fichier texte, ou vous pouvez en faire des tests.
Et c’est là tout l’intérêt des tests : ils servent de todo list. En les écrivant avant le code, vous vous assurez:
- d’avoir une idée claire de ce que vous allez faire.
- de savoir précisément où vous en êtes dans votre processus de développement (en faisant signaler les fonctions non écrites ou en faisant échouer leur test).
- que la nouvelle méthode que vous avez implémentée ne casse pas les précédentes.
C’est donc bel et bien un atout pour le développement agile, car cela permet d’assurer la simplicité, l’abstraction et la cohérence de votre code sans devoir revenir sur chaque méthode chaque fois que vous ajoutez un nouveau block de code : les tests vous préviendront si vous devez modifier quelque chose en amont. Cela n’exclue bien sûr pas la nécessité de faire des vrais tests manuels lorsque vous avez terminé une version de votre application, cela permet juste de rendre le développement plus rapide.
Mais où est la documentation?
Si vous avez déjà jeté un bref regard au fonctionnement des tests, vous avez sûrement été frustré de ne pas trouver les méthodes dans la documentation officielle de rails. Où est cet assert partout utilisé? Il y a bien toute une collection de assert_* dans ActionController::Assertions, mais les fonctions de base sont introuvables.
La raison en est simple : les outils de tests font partie d’un framework de tests indépendant et intégré dans rails (et faisant aujourd’hui partie de la librairie standard de ruby), Test::Unit. Vous trouverez dans sa documentation tous les éléments de base dont vous avez besoin.
Rails étend ensuite ces tests avec ses propres ajouts, et particulièrement pour les tests fonctionnels (tests effectués sur les contrôleurs).
Je n’ai pas trouvé d’articles à jour et de qualité en français expliquant en détail la marche à suivre pour utiliser les tests dans rails, je reviendrai donc dessus par la suite avec deux articles, l’un sur les tests unitaires (pour tester les modèles) et l’autre sur les tests fonctionnels (pour tester les contrôleurs).





