La valeur d’une approche particulière en matière de test dépend de l’importance critique du système en développement, et de la mesure dans laquelle un autre système essentiel dépend de celle-ci. Un simple script de livre d'or pour votre site Web pourrait difficilement être considéré comme essentiel à la mission, mais si le site Web sur lequel il est exploité pouvait être compromis par un bogue qui permettait une entrée non filtrée dans la base de données et que ce site offre un service essentiel, il devient soudainement beaucoup plus complexe. important pour que le script du livre d’or soit minutieusement testé. Il en va de même pour le code framework / library. Si vous développez un framework avec un bogue, chaque application qui utilise cette fonctionnalité du framework a également ce même bogue.
Le développement piloté par les tests vous apporte une couche supplémentaire de sécurité lors des tests. Si vous écrivez les tests à côté ou même après le code que vous voulez tester, vous risquez alors de vous tromper. Si vous écrivez tous les tests en premier, la manière dont le code fonctionne en interne ne peut pas influencer le but de vos tests. Par conséquent, il est moins probable que vous écriviez par inadvertance des tests qui considèrent qu'une sortie erronée particulière est correcte.
Le développement piloté par les tests encourage également vos développeurs à écrire du code facile à tester, car ils ne veulent pas se donner encore plus de travail! Un code facile à tester a tendance à être un code facile à comprendre, à réutiliser et à gérer.
Et la maintenance est l’endroit où vous récolterez vraiment les fruits du TDD. La grande majorité des efforts de programmation consacrés aux logiciels sont liés à la maintenance. Cela signifie apporter des modifications au code en direct pour lui donner de nouvelles fonctionnalités, corriger des bogues ou l'adapter à de nouvelles situations. Lorsque vous effectuez de telles modifications, vous voulez vous assurer que les modifications que vous apportez ont l'effet souhaité, et plus important encore, elles n'ont aucun effet d'entraînement inattendu. Si vous avez une suite de tests complète pour votre code, il est facile de vérifier que les modifications que vous apportez ne cassent pas autre chose, et si les modifications que vous apportez cassent autre chose, vous pouvez rapidement en trouver la raison. Les avantages sont à long terme.
Vous avez dit ceci dans votre question:
Je vois des avantages à écrire des tests pour certaines choses, mais très peu. Et bien que j'aime l'idée d'écrire le test en premier, je constate que je passe beaucoup plus de temps à essayer de déboguer mes tests pour les amener à dire ce que je veux dire vraiment que de déboguer le code réel. Ceci est probablement dû au fait que le code de test est souvent beaucoup plus compliqué que le code qu’il teste. J'espère que c'est simplement une inexpérience avec les outils disponibles (rspec dans ce cas).
Cela semble suggérer à moi que vous ne faites pas tout à fait le test. Un test unitaire est supposé être extrêmement simple, il ne s'agit que d'une séquence d'appels de méthode, suivie d'une assertion permettant de comparer le résultat attendu au résultat réel. Ils sont censés être simples car les bogues dans vos tests seraient désastreux et si vous introduisez un contrôle de boucle, de branchement ou un autre programme dans le test, il est plus probable que le test contienne un bogue. Si vous passez beaucoup de temps à déboguer des tests, cela signifie que vos tests sont trop compliqués et que vous devriez les simplifier.
Si les tests ne peuvent pas être simplifiés, cela seul suggère qu'il y a quelque chose qui cloche dans le code sous test. Par exemple, si votre classe a de longues méthodes, des méthodes avec beaucoup d'instructions if / elseif / else ou switch ou un grand nombre de méthodes ayant des interactions complexes dictées par l'état actuel de la classe, les tests devront nécessairement être extrêmement complexes. pour fournir une couverture complète du code et tester toutes les éventualités. Si votre classe a des dépendances codées en dur sur d’autres classes, cela augmentera encore le nombre d’arcades à franchir pour tester efficacement votre code.
Si vous maintenez vos classes petites et très concentrées, avec des méthodes courtes avec peu de chemins d'exécution et essayez d'éliminer l'état interne, les tests peuvent être simplifiés. Et c'est un peu le noeud de la question. Un bon code est par nature facile à tester. Si le code n'est pas facile à tester, il y a probablement quelque chose qui ne va pas.
Écrire des tests unitaires vous est bénéfique à long terme, et les éviter revient simplement à stocker les problèmes pour plus tard. Vous ne connaissez peut-être pas le concept de dette technique, mais cela fonctionne beaucoup comme une dette financière. Ne pas écrire de tests, ne pas commenter de code, écrire dans des dépendances codées en dur, ce qui constitue un moyen de s’endetter. Vous «empruntez» du temps en ménageant des étapes précoces, ce qui peut vous aider à respecter un délai serré, mais le temps que vous économisez plus tôt dans le projet est en prêt. Chaque jour qui passe sans nettoyer le code, le commenter correctement ou la construction d’une suite de tests vous coûtera de l’intérêt. Plus cela dure longtemps, plus les intérêts s'accumulent. Finalement, vous découvrirez que votre code est devenu un gâchis enchevêtré sur lequel vous ne pouvez pas apporter de modifications sans entraîner de conséquences inattendues.
Vous pourriez penser à écrire des tests unitaires tôt et à les tenir à jour comme une forme de "crédit technique". Vous mettez votre temps à la banque en consacrant très tôt le projet aux bonnes pratiques. Vous gagnerez de l'intérêt sur cette prévision plus tard, lorsque vous arriverez à la phase de maintenance du projet. Lorsque vous souhaitez effectuer un changement, vous pouvez facilement valider l'exactitude du changement et le fait qu'il n'a pas d'effets secondaires indésirables et que vous pouvez obtenir des mises à jour rapidement et sans tracas. Si des bogues se présentent, vous pouvez ajouter un nouveau test unitaire qui l'exerce, puis corrigez le bogue dans le code. Lors de la prochaine exécution du test unitaire, vous pourrez vérifier que le bogue a été corrigé et qu’il n’a causé aucun autre problème. De plus, vous éviterez les "régressions",
TL: DR - Oui, c’est une aide réelle, mais c’est un investissement. Les avantages ne deviennent apparents que plus tard.