Comment les tests d'intégration critiquent-ils le design?

38

Je lis un article sur les tests intégrés sur le blog de JB Rainsberger et je me demande en quoi un test d'intégration est plus dur avec notre conception?

Nous écrivons davantage de tests intégrés, qui sont plus volumineux et ne critiquent pas notre conception aussi sévèrement que les microtests.

Alex.U
la source
3
La question est déroutante. "En quoi un test d'intégration est plus sévère" ... "des tests intégrés, plus grands et qui ne critiquent pas notre conception avec la plus grande sévérité" - et maintenant?
AnoE
"test d'intégration"! = "test intégré". Je sais. Je n'aime pas ça non plus, mais c'est ce que ces mots veulent dire. "tests d'intégration" = "tests qui vérifient les points d'intégration (sans intégrer les choses)", tandis que "tests intégrés" = "(plus grands) tests qui intègrent des choses et vérifient l'ensemble intégré comme une seule chose". De cette façon, ces termes deviennent des opposés les uns des autres.
JB Rainsberger

Réponses:

46

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 vous comblez ses lacunes avec des objets fictifs . Cela conduit à un faible couplage (les choses ne dépendent pas les unes des autres) et à une grande cohésion (les choses qui vont ensemble restent ensemble). Ainsi, 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 aurez moins de chance de casser des choses en apportant ces changements. Cela ne résoudra pas tous vos problèmes mais cela peut aider.

Dans ce contexte, JB Rainsberger note que si vous rencontrez des difficultés pour écrire un test unitaire, votre conception présente probablement un problème qui en est la cause et, par conséquent, les tests critiquent implicitement la conception. Il affirme que c’est une bonne chose, car sans les petits tests, votre architecture est bien alignée, il est facile de s’écarter des bons modèles de conception - ce que les tests intégrés ne captureront pas.

Mise à jour : comme le note Rainsberger ci-dessous, il ne voulait pas que microtests soit synonyme 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.

Thorin Jacobs
la source
2
Je suis d'accord avec votre réponse de principe, mais pas avec la façon dont vous l'articulez. Quelqu'un qui pose cette question particulière a peu de chances de savoir ce que signifient les termes "moqueur", "couplage" et "cohésion", et vous ne les avez pas définis dans votre réponse.
Robert Harvey
3
C'est mieux, mais vous accordez plus de crédits aux tests unitaires que je ne le pense vraiment. Les tests unitaires informent principalement sur la testabilité de votre code. Il est moins clair de savoir si le fait de tester votre code confère automatiquement de meilleures caractéristiques de cohésion et de couplage, bien que ce soit certainement une influence positive. De plus, je pense que vous avez confondu "haute cohésion" avec le "principe de responsabilité unique"; cohésion signifie "choses qui vont ensemble" (voir l'article de Wikipedia ).
Robert Harvey
10
Enfin, "micro-tests" n'est pas le terme préféré. J'adore quand les blogueurs définissent leurs propres termes techniques.
Robert Harvey
2
@RubberDuck: Microtests (environ 16 900 résultats) vs tests unitaires (environ 193 000 000 résultats) . Pas même proche. Même si vous écrasez l'unité et testez ensemble, vous obtenez toujours 14 millions de résultats.
Robert Harvey
5
Veuillez ne pas assimiler "microtest" et "test unitaire" (voir ma réponse pour plus de détails); sinon, j'ai l'impression que vous avez compris ce que j'ai essayé de décrire.
JB Rainsberger
28

La version extrêmement courte: des tests plus petits, car ils exécutent de plus petites parties du système, contraignent naturellement ce que les programmeurs peuvent écrire, ce qui crée une opportunité de générer des commentaires plus précis (plus faciles à remarquer / plus difficiles à ignorer). Permettez-moi d'ajouter que cela ne conduit pas nécessairement à une meilleure conception, mais plutôt à une opportunité de détecter les risques de conception plus tôt.

Premièrement, pour préciser, quand je parle de "microtest", je veux dire "un petit test" et rien de plus. J'utilise ce terme parce que je ne veux pas dire "test unitaire": je ne veux pas m'impliquer 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 décidé peu à peu d’adopter «microtest» comme terme standard émergent pour cette idée.

Les tests plus volumineux, c'est-à-dire les tests qui exécutent de plus grandes parties du système dans leur partie "action", ont tendance à ne pas critiquer la conception de manière aussi claire ni aussi complète que des tests plus petits. Imaginez l'ensemble des bases de code pouvant passer avec succès un groupe de tests donné, ce qui signifie que je pourrais réorganiser le code et qu'il réussirait quand même ces tests. Pour de plus grands tests, cet ensemble est plus grand; pour des 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 devez entendre, et qui vous crie de transmettre l'urgence de manière à ce que les autres ne se sentent pas à l'aise Faire. Les tests intégrés, en revanche, restent silencieux et ne font que suggérer des problèmes, surtout lorsque vous n’avez plus le temps ni l’énergie nécessaire pour les résoudre. Des tests intégrés simplifient trop facilement les problèmes de conception.

Avec des tests plus volumineux (comme les tests intégrés), les programmeurs ont généralement tendance à avoir des ennuis: ils ont assez de liberté pour écrire du code enchevêtré qui leur permet de passer les tests, mais leur compréhension de ce code s'estompe rapidement au moment où ils passent à la tâche suivante. et d’autres ont des difficultés indues à lire le dessin 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 des microtests), les programmeurs ont généralement tendance à avoir des problèmes de spécification excessive: ils surchargent les tests en ajoutant des détails non pertinents, généralement par copier-coller à partir du test précédent, et ils se peignent eux-mêmes assez rapidement. dans un coin. Bonnes nouvelles: Je trouve qu'il est beaucoup plus facile et plus sûr de supprimer des détails superflus des tests plusieurs heures ou jours après que je les ai écrits que de séparer du code de production enchevêtré, mois après années, après l'avoir écrit. Au fur et à mesure que les erreurs disparaissent, une spécification excessive provoque des dommages de plus en plus évidents plus rapidement, et le programmeur d'alerte voit plus tôt qu'il est nécessaire de réparer le problème. Je considère cela comme une force: je remarque les problèmes plus tôt et les corrige avant que ces problèmes ne nous empêchent d’ajouter des fonctionnalités.

JB Rainsberger
la source
Que faites-vous du problème selon lequel les tests unitaires reposent davantage sur leurs modèles que sur le code réel, ce qui pose le problème des tests qui semblent réussir mais ne fonctionnent pas car personne ne les a alignés sur la réalité.
Zan Lynx
@ZanLynx J'ai longuement écrit à ce sujet. Commencez ici: blog.thecodewhisperer.com/series#integrated-tests-are-a-scam
JB Rainsberger
9

Il signifie qu'une bonne conception logicielle est mieux informée par les tests unitaires que par les tests d'intégration.

Voici pourquoi. Écrire des tests unitaires vous oblige à écrire du code testable par unité. Le code testable par unité 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, et non les interfaces internes qui relient votre logiciel.

Robert Harvey
la source