Cet article fait partie d’une série dédiés aux tests unitaires et au TDD. L’introduction est ici.
1. Le TDD se limite aux tests unitaires
Non, non et non. Le TDD, Test Driven Development ( originellement appelé ‘Test First Development’ ), consiste à définir ce que doit produire le code, le transcrire dans un (ou plusieurs) test(s) qui échoue(nt) (rouge) et ensuite écrire juste ce qu’il faut de code pour que le (ou les tests) réussisse(nt) (vert).
Un ‘unit test’ est souvent compris comme le fait de tester un bout du code (par exemple une méthode de classe), éventuellement en utilisant des mocks/stubs pour simuler les dépendances
Note: je ne partage pas cette définition, mais j’y reviendrais plus tard.
Les tests unitaires sont mis en avant pour leur vitesse et leur périmètre précis: ils sont petits, avec peu de dépendances, et donc s’exécutent vite (généralement). Quand un test unitaire échoue, il est facile d’identifier quelle partie du code est responsable (du problème).
Le TDD s’appuie en fait sur toutes sortes de tests. Par exemple, j’écris des tests de bout-en-bout dans ma pratique du TDD, et même des tests de performance.
Mais surtout, le sujet est le comportement PAS l’implémentation: vous écrivez un nouveau test quand vous avez besoin de couvrir une nouvelle exigence, un nouveau besoin. Vous n’écrivez pas un test à chaque fois que vous devez créer une nouvelle classe ou une nouvelle méthode. Une nuance subtile, mais importante; par exemple, vous ne devriez JAMAIS écrire de test uniquement parce que vous avez refactoré du code. Si c’est le cas, c’est que vous ne faisiez pas réellement du TDD.
Et quand Kent Beck parle du fait que les tests soient isolés, c’est qu’ils le sont les uns par rapport aux autres. Le résultat d’un test ne doit pas dépendre d’un autre test. Par exemple, avoir un test qui insère des entrées dans une table alors qu’un autre lit cette même table est probablement une mauvaise idée, puisque le résultat des tests est susceptible de dépendre de l’ordre d’exécution de ceux-ci.
Si vos tests ne sont pas isolés, il est très probable que vous allez en voir certains échouer sans raison identifiable, ou suite à une modification qui n’aurait pas dû les impacter; cela va aussi poser des problèmes pour l’exécution de ces tests en parallèle; dans ce dernier cas, vous allez voir des tests qui échouent aléatoirement et qui fonctionne très bien quand on les lance à nouveau (voir Heisenbug).
La suite est ici.