Ces derniers temps, j’ai eu plusieurs discussions avec d’autres informaticiens, orientées sur des sujets comme les méthodes agiles en général et plus particulièrement les tests unitaires. C’est toujours intéressant de confronter sa propre vision à celle des autres.
Une des choses qui m’a marqué, c’est que plus de la moitié des gens avec qui j’ai abordé le sujet avaient un raisonnement très binaire. C’est-à-dire que pour eux, 100% du code doit être couvert par des tests unitaires. C’est comme ça, ça ne doit pas être autrement. C’est simple et clair.
Sauf que… Cette vision des choses me gêne pour 3 raisons.
1. Le coût
Écrire des tests unitaires prend du temps. Cela a donc un coût. Tester l’intégralité du code oblige donc à y consacrer beaucoup de temps, ce qui augmente considérablement le budget en développement.
Le contre-argument habituel est de dire qu’en faisant appel au TDD (test driven development, dont je vous ai déjà parlé par le passé), ce coût est réduit. Ceci n’est pas complètement vrai : Le TDD force à commencer par écrire les tests, donc on est certains qu’ils existent. Au passage, on se creuse un peu la tête pour essayer d’imaginer les différents cas d’utilisation (légitimes ou générant des erreurs) dans lequel le code pourrait se retrouver. Mais le principe même des méthodes agiles, c’est de dire qu’on aura plus d’expérience demain ; donc il faudra forcément compléter ces tests au fil du temps. Ce qui ne pourra se faire qu’en cours de développement, voire même après les développements. Je connais beaucoup de développeurs qui utilisent la méthode TDD, et tous confessent devoir compléter leurs tests après coup.
Donc nous sommes d’accord, ça prend du temps, l’air de rien, et donc ça coûte cher. Il est inévitable de confronter ce coût à son utilité. C’est vrai, ça ; à quoi servent les tests unitaires ?
- Augmenter la stabilité des développements.
- Réduire les bugs de régression.
- Rendre le travail des développeurs plus confortable.
Le deuxième point découle du premier. Un code plus stable, qui se vérifie automatiquement, sera plus robuste face à des bugs de régression. Une fonctionnalité qui marche bien à un moment donné, mais qui se met à déconner à cause d’un effet de bord provoqué par un nouveau développement, ça arrive tous les jours. Les tests unitaires permettent de détecter cela au plus tôt et réduisent donc les risques.
Par contre, le troisième point me laisse un peu songeur. Je reste assez froid quand un informaticien me dit «Oui, mais avec 100% du code qui est testé, c’est beaucoup plus confortable pour nous !».
Certes, c’est vrai (encore que, voir plus bas). Mais sincèrement, même si je suis le premier à penser qu’une entreprise doit se soucier réellement du bien-être de ses employés, est-ce que le confort dont on parle vaut automatiquement le coût de l’écriture de tous ces tests ? Une entreprise a pour but de générer des bénéfices ; cela veut dire que chaque investissement doit être jugé à la lumière de ce qu’il va rapporter − ou de ce qu’il permettra de ne pas perdre (car si les tests unitaires ne font pas gagner d’argent, ils peuvent vous éviter d’en perdre beaucoup).
Tout ça pour dire qu’un développeur ne peut pas simplement dire que pour chaque heure de développement effectuée il lui faudra systématiquement une heure d’écriture de tests. Tout dépend du développement en question. En fait, c’est la même chose pour beaucoup d’autres points. Il y a des projets qui ne sont pas critiques pour l’entreprise, et pour lesquels on se permet tous les jours de faire l’impasse sur la qualité globale, la documentation, les tests ou autre chose. Tout simplement parce que l’important est de se confronter rapidement au marché, et que si le coût est élevé, le projet n’a alors plus lieu d’être.
2. La poudre aux yeux
Les tests unitaires ont toujours une part de “poudre aux yeux”. Ils peuvent donner un faux sentiment de sécurité. Le code est testé de manière automatique, alors on se repose sur la certitude que toute régression est impossible.
Oui, mais non. Il ne faut pas oublier que tester 100% du code ne veut pas dire que le code est testé à 100% (subtile nuance).
