Je suis en train de lire sur le billet de blog de J.B. Rainsberger sur les tests intégrés et je me demande en quoi un test d'intégration est plus dur avec notre conception?
Nous écrivons des tests plus intégrés, qui sont plus gros et ne critiquent pas notre conception aussi sévèrement que les microtests.
Les microtests peuvent aider à mener à une bonne conception . En écrivant de bons petits tests, vous testez délibérément une petite quantité de code et remplissez ses lacunes avec objets fictifs . Cela conduit à un faible couplage (les choses ne dépendent pas les unes des autres) et à une forte cohésion (les choses qui appartiennent ensemble restent ensemble). De cette façon, lorsque vous revenez en arrière et apportez des modifications, il est facile de trouver ce qui est responsable de ce que vous recherchez et vous êtes moins susceptible de casser les choses en effectuant le changement. Cela ne résoudra pas tout votre design mais cela peut vous aider.
Dans ce contexte, J.B. Rainsberger note que si vous avez du mal à écrire un test unitaire, vous avez probablement un problème avec votre conception qui cause la difficulté, et donc les tests critiquent implicitement la conception. Il postule que c'est une bonne chose, car sans les petits tests qui aident à maintenir votre architecture en ligne, il est facile de s'écarter de bons modèles de conception - que les tests intégrés ne captureront pas.
Mise à jour : comme le note Rainsberger ci-dessous, il ne voulait pas que les microtests soient synonymes de tests unitaires. Il a également fourni une réponse détaillée qui peut vous donner une idée plus précise de ce qu'il communiquait.
La version extrêmement courte: des tests plus petits, car ils exécutent des parties plus petites du système, limitent naturellement ce que les programmeurs peuvent écrire, ce qui crée une opportunité pour des commentaires plus nets (plus faciles à remarquer/plus difficiles à ignorer). Permettez-moi d'ajouter que cela ne conduit pas nécessairement à une meilleure conception, mais au contraire, cela crée plutôt la possibilité de remarquer les risques de conception plus tôt.
Tout d'abord, pour clarifier, quand je dis "microtest", je veux dire "un petit test" et rien de plus. J'utilise ce terme parce que je ne parle pas de "test unitaire": je ne veux pas me laisser entraîner dans des débats sur ce qui constitue une "unité". Je m'en fiche (du moins pas ici/maintenant). Deux personnes s'accorderont probablement plus facilement sur "petit" que sur "unité", j'ai donc progressivement décidé d'adopter "microtest" comme terme standard émergent pour cette idée.
Les tests plus importants, c'est-à-dire les tests qui exécutent des parties plus importantes du système dans leur partie "action", ont tendance à ne pas critiquer la conception aussi clairement ni aussi complètement que les tests plus petits. Imaginez l'ensemble de toutes les bases de code qui pourraient passer un groupe donné de tests, ce qui signifie que je pourrais réorganiser le code et qu'il passerait toujours ces tests. Pour des tests plus importants, cet ensemble est plus grand; pour les tests plus petits, cet ensemble est plus petit. Autrement dit, des tests plus petits contraignent davantage la conception, de sorte que moins de conceptions peuvent les faire passer. De cette façon, les microtests peuvent critiquer davantage la conception.
Je dis "plus durement" pour évoquer l'image d'un ami qui vous dit directement ce que vous ne voulez pas entendre, mais que vous avez besoin d'entendre, et qui vous crie de transmettre l'urgence d'une manière que les autres pourraient ne pas se sentir à l'aise Faire. Les tests intégrés, en revanche, restent silencieux et ne font allusion aux problèmes que lorsque vous n'avez plus le temps ni l'énergie pour les résoudre. Les tests intégrés rendent trop facile le balayage des problèmes de conception sous le tapis.
Avec des tests plus importants (comme des tests intégrés), les programmeurs ont généralement tendance à avoir des ennuis par négligence: ils ont suffisamment de liberté pour écrire du code enchevêtré qui réussit en quelque sorte les tests, mais leur compréhension de ce code s'estompe rapidement au moment où ils passent à la tâche suivante. et d'autres éprouvent des difficultés indues à lire le motif enchevêtré. C'est là que réside le risque de s'appuyer sur des tests intégrés. Avec des tests plus petits (comme les microtests), les programmeurs ont généralement tendance à avoir des problèmes en raison d'une sur-spécification: ils contraignent trop les tests en ajoutant des détails non pertinents, généralement en copiant/collant du test précédent, et ce faisant, ils se peignent relativement rapidement dans un coin. Bonne nouvelle: je trouve qu'il est beaucoup plus facile et plus sûr de supprimer les détails étrangers des tests plusieurs heures ou jours après les avoir écrits que de séparer le code de production enchevêtré des mois à des années après l'avoir écrit. Au fur et à mesure que les erreurs disparaissent, une sur-spécification fait des dégâts de plus en plus évidents plus rapidement, et le programmeur d'alerte voit plus tôt qu'ils doivent réparer les choses. Je considère cela comme une force: je constate des problèmes plus tôt et je les corrige avant que ces problèmes n'étranglent notre capacité à ajouter des fonctionnalités.
Il veut dire qu'une bonne conception logicielle est mieux informée par des tests unitaires que par des tests d'intégration.
Voici pourquoi. L'écriture de tests unitaires vous oblige à écrire du code testable à l'unité. Le code testable unitaire a tendance à être une meilleure conception que le code qui n'a pas de tests unitaires.
Les tests d'intégration n'informent pas votre code de la même manière car vous testez simplement la couche externe de votre logiciel, pas les interfaces internes qui connectent votre logiciel ensemble.