Quelle moquerie est "juste?"


10

J'ai intitulé la question en plaisantant parce que je suis sûr que "ça dépend", mais j'ai quelques questions spécifiques.

Travaillant dans un logiciel qui comporte de nombreuses couches de dépendance profondes, mon équipe s'est habituée à utiliser le mocking assez largement pour séparer chaque module de code des dépendances en dessous.

Par conséquent, j'ai été surpris que Roy Osherove ait suggéré dans cette vidéo que vous ne devriez utiliser la moquerie que quelque chose comme 5% du temps. Je suppose que nous sommes assis entre 70 et 90%. J'ai vu de temps à autre d' autres conseils similaires .

Je devrais définir ce que je considère être deux catégories de "tests d'intégration" qui sont si distinctes qu'on devrait vraiment leur donner des noms différents: 1) les tests en cours qui intègrent plusieurs modules de code et 2) les tests hors processus qui parlent aux bases de données, aux systèmes de fichiers, aux services Web, etc. C'est le type # 1 qui m'intéresse, les tests qui intègrent plusieurs modules de code tous en cours.

Une grande partie des conseils de la communauté que j'ai lus suggère que vous devriez préférer un grand nombre de tests unitaires à grains fins isolés et un petit nombre de tests d'intégration de bout en bout à grains grossiers, car les tests unitaires vous fournissent des informations précises sur l'endroit exact où des régressions ont peut-être été créées, mais les tests grossiers, qui sont lourds à mettre en place, vérifient en fait davantage de fonctionnalités de bout en bout du système.

Compte tenu de cela, il semble nécessaire d'utiliser assez fréquemment la simulation pour isoler ces unités de code distinctes.

Étant donné un modèle d'objet comme suit:

entrez la description de l'image ici

... Considérez également que la profondeur de dépendance de notre application va beaucoup plus loin que je ne pourrais le faire dans cette image, de sorte qu'il existe plusieurs couches N entre la couche 2-4 et la couche 5-13.

Si je veux tester une simple décision logique prise dans l'unité # 1, et si chaque dépendance est injectée par le constructeur dans le module de code, cela en dépend tel que, disons, 2, 3 et 4 sont injectés par le constructeur dans le module 1 de l'image, je préfère de loin injecter des simulacres de 2, 3 et 4 en 1.

Sinon, j'aurais besoin de construire des instances concrètes de 2, 3 et 4. Cela peut être plus difficile que juste une frappe supplémentaire. Souvent 2, 3 et 4 auront des exigences de constructeur qui peuvent être difficiles à satisfaire et selon le graphique (et selon la réalité de notre projet), je devrai construire des instances concrètes de N à 13 pour satisfaire les constructeurs de 2, 3 et 4.

Cette situation devient plus difficile lorsque j'ai besoin de 2, 3 ou 4 pour se comporter d'une certaine manière afin de pouvoir tester la décision logique simple dans # 1. J'ai peut-être besoin de comprendre et de "raisonner mentalement" à la fois sur l'ensemble du graphique / arbre d'objet pour que 2, 3 ou 4 se comportent de la manière nécessaire. Il semble souvent beaucoup plus facile de faire myMockOfModule2.Setup (x => x.GoLeftOrRight ()). Returns (new Right ()); pour tester que le module 1 répond comme prévu lorsque le module 2 lui dit d'aller à droite.

Si je devais tester des instances concrètes de 2 ... N ... 13 ensemble, les configurations de test seraient très grandes et en grande partie dupliquées. Les échecs de test peuvent ne pas faire un très bon travail pour localiser les emplacements des échecs de régression. Les tests ne seraient pas indépendants ( autre lien de support ).

Certes, il est souvent raisonnable de faire des tests basés sur l'état plutôt que sur l'interaction de la couche inférieure, car ces modules ont rarement d'autres dépendances. Mais il semble que la moquerie soit presque nécessaire par définition pour isoler tous les modules au-dessus du plus bas.

Compte tenu de tout cela, quelqu'un peut-il me dire ce qui pourrait me manquer? Notre équipe utilise-t-elle trop les simulacres? Ou y a-t-il peut-être une hypothèse dans les conseils de tests unitaires typiques que les couches de dépendance dans la plupart des applications seront suffisamment peu profondes pour qu'il soit en effet raisonnable de tester tous les modules de code intégrés ensemble (ce qui rend notre cas "spécial")? Ou peut-être différemment, notre équipe ne délimite-t-elle pas adéquatement nos contextes délimités?


Il me semble que votre application pourrait bénéficier d'un couplage plus lâche. en.wikipedia.org/wiki/Loose_coupling
Robert Harvey

1
Or is there perhaps some assumption in typical unit testing guidance that the layers of dependency in most applications will be shallow enough that it is indeed reasonable to test all of the code modules integrated together (making our case "special")? <- Ça.
Robert Harvey

A noter également: le but des tests de régression (notamment les tests d'intégration) est de prouver que votre logiciel fonctionne toujours, pas forcément d'identifier où il se casse. Vous pouvez le faire avec le dépannage, résoudre le problème, puis couvrir la rupture spécifique avec des tests unitaires supplémentaires.
Robert Harvey

J'aurais dû être plus clair dans le message d'origine, pour dire que le module 1 ne connaît que I2, I3 et I4. Le module 2 ne connaît que I5, I6 et I7. Ce n'est que l'objectif discutable de tester sans utiliser de maquette que je fournirais un 2, 3 et 4 à 1 concret, conduisant aux défis que j'ai décrits. Sinon, nous nous retrouvons en utilisant des simulateurs beaucoup plus de 5% du temps.
ardave

J'ai en quelque sorte plaisanté en disant que notre cas était "spécial" après avoir lu un article de blog sur de nombreuses équipes défiant les conventions précieuses parce qu'elles pensaient à tort que leur situation était "spéciale". Mais si tel est notre cas, cela expliquerait la disparité entre certains des conseils communautaires que j'ai lus et certaines des expériences réelles de mon équipe. (5% vs 70-90%)
ardave

Réponses:


4

Notre équipe utilise-t-elle trop les simulacres?

Pas à première vue.

Si vous avez 1 à 13 modules, chacun doit avoir ses propres tests unitaires et toutes les dépendances (non triviales, non fiables) doivent être remplacées par des versions de test. Cela peut signifier des simulations, mais certaines personnes sont pédant avec les noms, donc les contrefaçons, les cales, les objets nuls ... certaines personnes appellent toutes les implémentations de test des "simulations". Cela pourrait être la source de la confusion quant au montant «correct».

Personnellement, j'appelle simplement tous les objets de test des «simulacres», car il n'est souvent pas utile de faire la distinction entre les divers. Tant qu'ils gardent mes tests unitaires rapides, isolés et résistants ... Je me fiche de leur nom.


Je me demande alors s'il y a une orientation générale là - bas quand il est préférable de modules de code de test dans l' isolement par rapport à tester plus d'un module de code, intégré ensemble. Il semble que dès que j'intègre deux modules que j'aurais pu autrement isoler, je m'ouvre à une multitude de problèmes indésirables: manque de localisation des causes de régression / échec de plusieurs tests pour une seule régression, configurations de test excessives, etc. J'ai mon propre sens intuitif ("écouter les tests") mais cela m'a laissé au niveau de simulation 70-90%.
ardave

1
@nono - D'après mon expérience, vous devriez tout tester isolément, pour les raisons que vous mentionnez. Les seules choses que vous ne testez pas isolément sont des choses que vous ne pouvez pas car elles vont directement à l'encontre d'un système de fichiers ou d'une autre ressource externe ( quelque chose doit le faire après tout).
Telastyn

Après avoir mâché dessus pendant quelques jours, la vôtre semble être la meilleure explication possible: si l'on devait utiliser la définition stricte de "maquette" comme type de test double utilisé pour l'interaction rétrospective / vérification du comportement, par opposition à un test fictif double ou un test double qui est configuré à l'avance pour simuler un certain comportement, alors oui, j'ai pu voir la liquidation au niveau de 5%.
ardave
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.