Personnellement, je suis assez d'accord avec son point. J'utilise plutôt une méthode qui consiste à faire du prototypage, une sorte de POC, puis à refactorer et créer des tests après la validation. Et je crois que c'est logique de penser que le TDD ne correspond pas à cette façon de travailler. Je ne vais pas jusqu'à dire que c'est une mode, c'est une méthode comme les autres, ce qui signifie qu'elle se prête bien à certaines situations et moins bien à d'autres
. Le problème c'est que pour tout ce qui est méthodologie agile et autres trucs mainstream, les adeptes sont juste extrêmement dogmatiques.
Il condamne notamment l'interdiction d'avoir recours à des opérations lentes (lire un fichier, interroger une DB). Je reconnais sans difficulté qu'il faut l'éviter si possible, le problème c'est que souvent, c'est un compromis. Tester même succinctement une application qui utilise une base de donnée sans faire de véritables requêtes, c'est assez complexe. Ca peut vous demander d'avoir une abstraction très élevée et de concevoir beaucoup de mock objects. Il suffit d'essayer de mocker un simple "panier d'achat" en mémoire, faisant intervenir différentes entités (Produits, Inventaire etc...) pour se rendre compte que ça demande un paquet de code à la main et que rendre ce type de test possible a aussi des implications sur la conception. Ces tests sont pas forcément écrits une fois pour toutes, ils peuvent demander une maintenance si vous refactorez.
Le danger lorsqu'on veut du tout TDD, c'est de complexifier trop son architecture pour les besoins des tests unitaires, puis de s'enfoncer dans le micro-test. Car le problème qui devient évident lorsqu'on teste une application basée sur une source de données externe, c'est que même si les tests passent, on sait jamais si ça passe tant qu'on ne l'a pas exécutée pour de vrai. A ce moment là, est-ce que ça vaut la peine d'avoir recours intensif au mock si c'est beaucoup de boulot et qu'au final ça prouve pas grand chose??? C'est encore plus vrai si vous utilisez des ORM, pouvez-vous garantir que vos mocks se comportent comme les objets réels (style proxy hibernate)?
Cela nous amène à un autre de ses points, il y a des choses (beaucoup de choses en fait), ou le mieux c'est clairement de se contenter de tests d'intégration de haut niveau. Laisser tomber le test "classe par classe" puis tester des "actions" impliquant plusieurs classes, de véritables transactions qui testent aussi bien les couches métier que les couches inférieures (par exemple accès aux données) sur lesquelles elles reposent. Ce sont des tests plus lourds, longs à exécuter, mais ils sont très proches de la réalité. L'étape plus haut, ce sont les tests pratiqués directement sur l'interface utilisateur, style selenium, qui peuvent aussi avoir un rôle complémentaire intéressant.
Je cite son post en rapport avec ce point :
I rarely unit test in the traditional sense of the word, where all dependencies are mocked out, and thousands of tests can close in seconds. It just hasn't been a useful way of dealing with the testing of Rails applications. I test active record models directly, letting them hit the database, and through the use of fixtures. Then layered on top is currently a set of controller tests, but I'd much rather replace those with even higher level system tests through Capybara or similar.
I think that's the direction we're heading. Less emphasis on unit tests, because we're no longer doing test-first as a design practice, and more emphasis on, yes, slow, system tests. (Which btw do not need to be so slow any more, thanks to advances in parallelization and cloud runner infrastructure).
Je suis 100% d'accord avec ça, tester les opérations au niveau transaction métier, voire au niveau utilisateur, il y a que ça de vrai. Ce sont des tests souvent raisonnablement faciles à écrire et à maintenir vu qu'ils se soucient assez peu de ce qui se passe sous le capot, ainsi vous pourrez refactorer les couches basses sans réécrire la moitié du code de test. Peut être long à exécuter (genre chargement d'un script DB initial qui peut prendre quelques secondes), mais au moins les résultats sont la vérité vraie.
Est-ce que pour autant on devrait plus faire de test unitaires (au sens test de classe)? Non du tout, j'y ai recours assez souvent quand je teste des algos pointus qui doivent absolument être blindés. Il m'arrive même d'appliquer le TDD pour ceux-ci. Donc je le répète :
- oui pour le test en général
- oui pour le test unitaire
- non pour le micro-test systématique
- non pour l'obligation stricte d'écrire les tests avant
Après qu'on veuille imposer à un débutant qu'il écrive les tests avant pour le forcer à mener la réflexion sur l'architecture passe encore. Mais l'imposer à un professionnel chevronné, c'est encore du dogmatisme. Il faudrait qu'on commence à comprendre que dans ce métier, il y a pas de standards qui tiennent. On résout des problèmes en prenant des aides partout où on en trouve, que ce soit des outils, des méthodologies, des techniques ou des idées.
3 |
1 |