Question

Cela semblait susciter un peu de conversation sur une autre question et je crut digne de tourner dans sa propre question.

Le principe DRY semble être notre arme de choix pour l'entretien combattre problèmes, mais qu'en est le maintien du code de test ? Faites les mêmes règles de base appliquer?

Quelques voix fortes dans la communauté des développeurs de tests sont d'avis que l'installation et le démontage sont nocifs et doivent être évités ... pour ne citer que quelques-uns:

En fait, xUnit.net les a retirés du cadre tout à fait pour cette raison (Mais il y a façons de contourner cette autolimitation ) .

Quelle a été votre expérience? Avez-setup / désassemblage blessé ou aide maintenabilité test?

UPDATE : faire des constructions plus à grains fins comme ceux disponibles dans junit4 ou TestNG (@BeforeClass, @BeforeGroups, etc.) faire une différence

Était-ce utile?

La solution

La majorité (sinon la totalité) de valide utilise des méthodes de montage et de démontage peuvent être écrites comme des méthodes d'usine qui permet de sécher sans entrer dans des questions qui semblent être en proie à la configuration / paradigme teardown .

Si vous implémentez le désassemblage, généralement cela signifie que vous n'êtes pas faire un test unitaire, mais plutôt un test d'intégration. Beaucoup de gens utilisent cela comme une raison de ne pas avoir un désassemblage, mais l'OMI, il devrait être à la fois l'intégration et test unitaire. Personnellement, je les séparer dans des ensembles séparés, mais je pense qu'un bon cadre de test devrait être en mesure de soutenir les deux types de tests. Pas tous les bon test va être les tests unitaires.

Cependant, avec la configuration, il semble y avoir un certain nombre de raisons pour lesquelles vous avez besoin de faire des choses avant un test est exécuté en réalité. Par exemple, la construction de l'état de l'objet à préparer pour le test (par exemple la mise en place d'un cadre d'injection de dépendance). Ceci est une raison valable pour une installation, mais pourrait tout aussi bien être fait avec une usine.

En outre, il y a une distinction entre la classe et la configuration niveau de la méthode / désassemblage. Cela doit garder à l'esprit lorsque l'on considère ce que vous essayez de faire.

Mon plus gros problème que j'ai eu à l'utilisation du paradigme setup / désassemblage est que mes tests ne suivent pas toujours le même schéma. Cela m'a mis en utilisant des modèles d'usine à la place, ce qui me permet d'avoir DRY tout en étant en même temps lisible et pas du tout confus à d'autres développeurs. La voie d'usine, je suis en mesure d'avoir mon gâteau et le manger à.

Autres conseils

Ils ont vraiment aidé à notre maintenabilité de test. Nos tests « unitaires » sont en fait des tests complets d'intégration de bout en bout qui écrivent à la DB et vérifier les résultats. Pas ma faute, ils étaient comme ça quand je suis arrivé ici, et je travaille à changer les choses.

Quoi qu'il en soit, si l'on test a échoué, il a continué à la suivante, en essayant d'entrer dans le même utilisateur à partir du premier test dans la base de données, il ne respecte pas une contrainte d'unicité, et les échecs tout en cascade à partir de là. Déplacement de la création d'utilisateur / suppression dans le [Fixture] [| SetUp] TearDown méthodes nous a permis de voir le seul test qui a échoué sans tout détraqué, et m'a rendu la vie beaucoup plus facile et moins stabby

.

Je pense que le principe SEC applique tout autant pour les tests comme pour le code, mais son application est différente. Dans le code que vous allez à longueurs beaucoup plus à littéralement pas faire la même chose dans deux parties différentes du code. Lors des tests, la nécessité de le faire (faire beaucoup de la même configuration) est certainement une odeur, mais la solution n'est pas nécessairement à extraire la duplication dans une méthode de configuration. Il peut être rendre l'état plus facile à mettre en place dans la classe elle-même ou pour isoler le code en cours de test il est donc moins dépendante de ce montant de l'Etat pour être significatif.

Compte tenu de l'objectif général de tester qu'une seule chose par test, il est vraiment impossible d'éviter de faire beaucoup de la même chose encore et encore, dans certains cas (comme la création d'un objet d'un certain type). Si vous trouvez que vous avez beaucoup de cela, il peut être utile de repenser l'approche de test, telles que l'introduction des tests paramétrées et autres.

Je pense que la configuration et teardown devraient être principalement pour établir l'environnement (comme les injections pour rendre l'environnement un test un plutôt qu'une production un), et ne doivent pas contenir des mesures qui font partie intégrante du test.

Je suis d'accord avec tout ce que Joseph a à dire, en particulier la partie sur tearDown étant un signe de l'écriture de tests d'intégration (et 99% du temps est ce que je l'ai utilisé pour), mais en plus de ce que je dirais que l'utilisation de la configuration est un bon indicateur du moment où les tests doivent être logiquement regroupés et quand ils devraient être divisés en classes de test multiples.

Je n'ai aucun problème avec de grandes méthodes de configuration lors de l'application des tests de code existant, mais l'installation devrait être commune à tous les tests dans la suite . Lorsque vous vous trouvez avoir la méthode de configuration vraiment faire plusieurs bits de configuration, alors il est temps de diviser vos tests en plusieurs cas.

Après les exemples "test Driven" , la méthode de configuration se réalise de enlever le double emploi dans les cas de test.

J'utilise la configuration assez fréquemment en Java et Python, souvent de mettre en place des collaborateurs (réel ou test, selon le cas). Si l'objet sous test n'a pas seulement les constructeurs ou les collaborateurs que les constructeurs je vais créer l'objet. Pour une simple classe de valeur habitude, je ne prends pas la peine avec eux.

J'utilise très rarement teardown en Java. En Python, il a été le plus souvent utilisé parce que j'étais plus susceptibles de changer d'état global (en particulier, les modules de rapiéçage de singe pour permettre aux utilisateurs de ces modules en cours de test). Dans ce cas, je veux un désassemblage qui garanti d'être appelé si un test a échoué.

Les tests d'intégration et des tests fonctionnels (qui utilisent souvent le cadre de xUnit) sont plus susceptibles d'avoir besoin montage et du démontage.

Le point à retenir est de penser à accessoires , non seulement DRY.

Je n'ai pas un problème avec configuration test et méthodes teardown en soi.

La question pour moi est que si vous avez une configuration de test et la méthode de désassemblage, cela implique que le même objet de test est réutilisé pour chaque test. Ceci est un vecteur d'erreur potentiel, comme si vous oubliez de nettoyer un élément de l'état entre les tests, les résultats des tests peuvent devenir dépendants d'ordre. Ce que nous voulons vraiment est des tests qui ne partagent pas l'État.

xUnit.Net se débarrasse de l'installation / désassemblage, car il crée un nouvel objet pour chaque test qui est exécuté. En substance, le constructeur devient la méthode de configuration et le finaliseur devient la méthode de désassemblage. Il n'y a pas d'Etat (niveau d'objet) a eu lieu entre les tests, ce qui élimine ce vecteur d'erreur potentiel.

La plupart des tests que je vous écris avoir une certaine quantité de configuration, même si elle est juste la création des simulacres j'ai besoin et le câblage de l'objet testé jusqu'à la simulacres. Ce qu'ils ne le font pas est de partager tout état entre les tests. Teardown est tout simplement en vous assurant que je ne partage pas cet état.

Je n'ai pas eu le temps de lire à la fois de ce que vous avez publié, mais je en particulier aimé ce commentaire:

  

chaque test est forcé de faire l'initialisation de ce dont il a besoin pour fonctionner.

Configuration et le démontage sont des méthodes pratiques - ils ne devraient pas tenter de faire beaucoup plus que l'initialisation d'une classe par son constructeur par défaut, etc. Code commun que trois tests doivent dans une classe de cinq test ne doit pas apparaître là - chacun les trois tests doivent appeler ce code directement. Cela permet également des tests de marcher sur les pieds et de briser un tas de tests de l'autre juste parce que vous avez changé une routine de initalization commun. Le principal problème est que ce sera appelé avant tous les tests - non seulement des tests spécifiques. La plupart des tests doivent être simples et les plus complexes auront besoin du code d'initialisation, mais il est plus facile de voir la simplicité des tests simples lorsque vous n'avez pas à tracer par une initialisation complexe dans la destruction mis en place et complexe démontage en penser à ce que le test est en fait censé accomplir.

Personnellement, j'ai trouvé la configuration et teardown ne sont pas toujours mal, et que ce raisonnement est un peu dogmatique. Mais je n'ai aucun problème les qualifiant odeur pour les tests unitaires. Je sens leur utilisation doit être justifiée, pour quelques raisons:

  1. Code d'essai est la procédure par sa nature. En général, la configuration / désassemblage faire ont tendance à réduire la lisibilité de test / mise au point.
  2. Méthodes d'initialisation ont tendance à plus que ce qui est nécessaire pour un test unique. En cas d'abus, ils peuvent devenir difficiles à manier. Objet mères, les constructeurs de données de test, peut-être des cadres comme factorygirl semblent mieux à l'initialisation des données de test.
  3. Ils encouragent « le contexte ballonnement. » - plus le contexte de test devient, moins maintenable il sera

Dans la mesure où ma configuration / désassemblage ne fait pas cela, je pense que leur utilisation est justifiée. Il y aura toujours un certain chevauchement dans les tests. Neal Ford dit cela comme « Les tests peuvent être humide, mais pas de trempage ... » En outre, je pense que leur utilisation est plus justifiée quand on ne parle pas de tests unitaires spécifiquement, mais les tests d'intégration plus large.

travail sur moi-même, cela n'a jamais vraiment été un problème. Mais je l'ai trouvé très difficile de maintenir des suites de test dans un cadre de l'équipe, et il a tendance à être parce que nous ne comprenons pas le code de immédiatement, ou ne veulent pas avoir à parcourir pour la comprendre. Du point de vue de test, je l'ai trouvé en permettant une certaine duplication dans les tests facilite ce fardeau.

J'aimerais savoir comment les autres se sentent à ce sujet, cependant.

Si vous avez besoin d'installation et désassemblage pour faire vos tests unitaires de travail, peut-être ce que vous vraiment besoin est des objets fantaisie?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top