Contrôler l'ordre d'exécution des tests unitaires dans Visual Studio
Bon, je suis en fait à la recherche de la bonne information sur ce sujet.
J'ai une série de Tests Unitaires qui appellent une classe statique qui, une fois initialisé, définit les propriétés qui ne peuvent pas (ou je ne souhaite pas) changer.
Mon problème est que je ne peut pas appliquer un ensemble de commande pour les tests à exécuter. Si je pouvais, j'ai pu les exécuter d'une manière telle que les propriétés statiques serait fixé de manière fiable, et je pouvais Affirmer sur eux, mais malheureusement, le Microsoft.VisualStudio.TestTools.UnitTesting cadre que je viens de pistes dans un ordre apparemment aléatoire.
Donc, j'ai trouvé ce http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.priorityattribute.aspx qui est dit dans les Remarques de la section "Cet attribut n'est pas utilisé par le système de test. Il est fourni à l'utilisateur pour personnaliser fins." Hein? Qu'en est-il alors? Attendent-ils de moi pour écrire mes propres tests wrapper pour profiter de ce fabuleux attribut (dont je pourrais facilement écrire moi-même si je voulais aller à ce niveau de l'effort...)
Donc, assez de la diatribe; ligne de Fond, il est un moyen pour contrôler l'ordre dans mes tests unitaires exécuter?
[TestMethod]
[Priority(0)]
etc. ne semble PAS fonctionner, ce qui est logique, puisque Microsoft indique qu'il ne sera pas.
Aussi, s'il vous plaît pas de commentaires à propos de "violation de l'isolement". TestClass isolats de ce que je suis en train de tester, et non les Méthodes. Peu importe, chaque test peut être exécuté indépendamment seulement beaux, mais ils ne peuvent pas être exécutées dans un ordre aléatoire comme il n'existe aucun moyen d'abattre la classe statique.
Oh, je connais aussi "Test Ordonné".
- Êtes-vous en mesure d'expliquer pourquoi vos tests sont d'ordre à charge? Je le prends les tests sont essentiellement progressivement les essais Statiques de la Classe?
- Vos tests unitaires ne doivent pas dépendre de l'ordre. Cette mort cérébrale statique de la classe est de rendre votre code invérifiables. Si vous ne pouvez pas "tear it down", alors ce n'est pas le seul problème que vous allez avoir lors de tests unitaires.
- La classe statique n'est pas le mien - oui, il doit avoir été écrit comme un singleton. Malheureusement, parfois, il vous suffit de jouer la (merde) les cartes qui vous sont distribuées. Je suis à l'aide de Faux autant que possible de les enlever de l'équation, mais je ne peux pas l'éliminer.
- l'impossibilité de détruire une classe statique n'est pas une question nouvelle. Les gens semblent s'en passer. Encore une fois, je ne demande pas de commentaires sur la "mort cérébrale" cadre de, seulement si il existe un moyen de le surmonter. 🙂
- Vous ne pouvez pas réinitialiser le statique de la classe de contexte à chaque fois dans une TestInitialize? L'un des principes de base de l'unité de test est celle de l'indépendance, n'essayez pas de contrôler l'ordre d'exécution. Vous n'êtes pas la "violation de l'isolement", mais de violer les principes de base qui fait un test un test unitaire.
- lorsque la classe statique est "pas toi" et est privé/interne et appartient à un tiers de la bibliothèque, vous êtes littéralement vissé, à moins d'utiliser l'approche que j'ai esquissé dans ma partie-offtopic réponse. Brièvement: Domaines D'Application. Inconvénients: autochtone/non géré état fait encore mal.
- Même si vous aviez une Méthode pour réinitialiser le stastic classe, il faudrait toujours être tous dans le même domaine d'application et de vos appels à la
Reset()-Method
pourrait écraser vos Tests, sauf si vous exécutez un par un. - Dans Visual Studio 2015, les choses ont un peu changé. Dans l'Explorateur de solutions, cliquez du bouton droit sur l'unité d'un projet de test, cliquez sur Ajouter>OrderedTest. En faisant cela ajoute un nouveau fichier au projet. Lorsque vous ouvrez ce fichier, vous aurez à cliquer sur les méthodes de test au sein de votre projet et ajouter 1 ou plusieurs fois à cette épreuve.
- Voir mon commentaire ci-dessous sur ClassInitialize attribut, aussi je crois OrderedTests sont assez faciles à mettre en œuvre et MS sont acceptées.
- On peut avoir beaucoup de raisons pour exécuter commandé des tests. Et quand on en a besoin pour exécuter commandé des tests, on n'a vraiment pas besoin de commentaires qui ne sont pas vraiment aider, comme de dire que vous ne devriez pas faire ça, etc. Je suis en demandant poliment que la prochaine fois, s'il vous plaît ignorer ce genre de commentaires et d'essayer d'être utile. Ou juste passer le fil complètement. Je vais ajouter ma réponse en une minute.
- Une autre raison pourquoi je devrais être capable de définir l'ordre d'exécution des tests: je voudrais que mes tests de base pour être exécuté avant que le plus compliqué des classes, qui dépendent de l'classes de base. Je préfère voir cette dépendance au lieu d'avoir les tests en cours d'exécution par ordre alphabétique (Visual Studio 2017)
Vous devez vous connecter pour publier un commentaire.
Fusionner vos tests en un seul géant de test fonctionne. Pour faire la méthode d'essai plus lisible, vous pouvez faire quelque chose comme
En fait le problème que vous avez suggère que vous devriez probablement améliorer la testabilité de la mise en œuvre.
Vous pouvez Utiliser Playlist
Clic droit sur la méthode de test -> Ajouter à la liste de lecture -> Nouvelle liste de lecture
l'ordre d'exécution sera comme vous l'ajouter à la liste de lecture, mais si vous voulez le changer, vous avez le fichier
Je n'ai pas vu personne mentionner le
ClassInitialize
attribut de méthode. Les attributs sont assez directe.Créer des méthodes qui sont marqués avec le
[ClassInitialize()]
ou[TestInitialize()]
attribut de préparer les aspects de l'environnement dans lequel votre unité de test sera exécuté. Le but de ceci est d'établir un état connu pour l'exécution de votre unité de test. Par exemple, vous pouvez utiliser le[ClassInitialize()]
ou la[TestInitialize()]
méthode de copier, modifier, ou créer un certain nombre de fichiers de données de test à utiliser.Créer des méthodes qui sont marqués avec le
[ClassCleanup()]
ou[TestCleanUp{}]
attribut pour revenir à l'environnement à un état connu, après un test a été exécuté. Cela pourrait signifier la suppression de fichiers ou de dossiers, ou le retour d'une base de données à un état connu. Un exemple de ceci est de rétablir une base de données d'inventaire à un état initial après le test d'une méthode qui est utilisée dans une commande d'entrée de l'application.[ClassInitialize()]
UtilisationClassInitialize
d'exécuter du code avant de vousexécutez le test de la première de la classe.
[ClassCleanUp()]
UtilisationClassCleanup
d'exécuter du code après tous les testsune classe l'ont exécuté.
[TestInitialize()]
UtilisationTestInitialize
d'exécuter du code avant de vous lancerchaque test.
[TestCleanUp()]
UtilisationTestCleanup
d'exécuter du code après chaque test aexécutez.
Comme vous devriez le savoir maintenant, les puristes disent qu'il est interdit d'exécuter commandé des tests. Cela pourrait être vrai pour les tests unitaires. MSTest et autres frameworks de Test sont utilisés pour exécuter pure de test de l'unité, mais aussi de tester l'INTERFACE utilisateur, plein de tests d'intégration, you name it. Peut-être que nous ne les appelons pas des infrastructures de Test Unitaire, ou peut-être que nous devrions et de les utiliser en fonction de nos besoins. C'est ce que la plupart des gens font de toute façon.
Je suis en cours d'exécution VS2015 et je dois exécuter les tests dans un ordre donné, parce que je suis en cours d'exécution de l'INTERFACE utilisateur de tests (Selenium).
Priorité - Ne rien faire du tout
Cet attribut n'est pas utilisé par le système de test. Il est fourni à l'utilisateur pour personnaliser fins.
orderedtest - il fonctionne, mais je ne le recommande pas car:
exécutée. Si vous modifiez un nom de méthode, vous devez réparer le fichier.
qui classe exécute ses premiers essais.
D'autres suggestions dans ce thread sont intéressantes, mais vous perdez la possibilité de suivre la progression du test sur l'Explorateur de tests.
Vous êtes de gauche avec la solution que puriste conseillera contre, mais en fait, est la solution qui fonctionne: trier par ordre de déclaration,.
La MSTest exécuteur utilise un interop qui parvient à obtenir l'ordre de déclaration, et cette astuce fonctionnera jusqu'à ce que Microsoft change le test exécuteur code.
Cela signifie que la méthode de test est déclaré en premier lieu s'exécute avant que l'un qui est déclaré à la deuxième place, etc.
Pour rendre votre vie plus facile, l'ordre de déclaration doit correspondre à l'ordre alphabétique, ce qui est indiqué dans l'Explorateur de tests.
Je vous suggère fortement de certains vieux et testé règles:
TRÈS IMPORTANT
Pour exécuter les tests par l'ordre de déclaration, vous devez utiliser Exécuter Tous les dans l'Explorateur de tests.
Dire que vous avez 3 classes de test (dans mon cas tests pour Chrome, Firefox et Edge). Si vous sélectionnez une classe donnée et cliquez-droit sur Exécuter les Tests Sélectionnés il commence généralement par l'exécution de la méthode déclarée dans la dernière place.
Encore une fois, comme je l'ai dit avant, déclaré ordre et ordre indiqué doit correspondre, sinon vous aurez de gros problèmes en un rien de temps.
Comme les commentateurs l'a déjà souligné, les tests reposent sur d'autres points d'essai à un défaut de conception. Néanmoins, il existe des moyens pour y parvenir. Comme répondu dans une question posée ici, vous pouvez créer commandé des tests unitaires, qui est essentiellement un seul conteneur de test qui assure la séquence de test.
Voici un guide sur MSDN: http://msdn.microsoft.com/en-us/library/ms182631.aspx
Puisque vous avez déjà mentionné le Test Ordonné que la fonctionnalité de Visual Studio framework de tests de fournitures, je vais en tenir compte. Vous semblez aussi avoir conscience que ce que vous essayez d'accomplir afin de tester cette Classe Statique est une "mauvaise idée", donc je vais ignorer que pour.
Au lieu de cela, permet de se concentrer sur la façon dont vous pouvez effectivement être en mesure de garantir que vos tests sont exécutés dans l'ordre que vous voulez. Une option (tel que fourni par @gaog) est "une méthode de test, de nombreuses fonctions de test", l'appel de vos fonctions de test dans l'ordre que vous voulez à partir d'une seule fonction marquée avec le
TestMethod
attribut. C'est la façon la plus simple, et le seul inconvénient est que la première fonction de test de l'échec permettra d'éviter toutes les autres fonctions de test de l'exécution de.Avec votre description de la situation, c'est la solution que je vous suggère de l'utiliser.
Si la partie en gras est un problème pour vous, vous pouvez accomplir un ordre d'exécution des isolés tests en mettant dans la construction de pilotés par les données de test de fonctionnalité. Son plus compliqué et se sent un peu sale, mais il fait le travail.
En bref, vous pouvez définir une source de données (comme un fichier CSV, ou une table de base de données) qui contrôle l'ordre dans lequel vous avez besoin pour exécuter vos tests, et les noms des fonctions qui contiennent en réalité le test de la fonctionnalité. Vous accrochez ensuite que source de données dans un pilotés par les données de test, l'utilisation de la lecture séquentielle de l'option, et l'exécution de vos fonctions, dans l'ordre que vous voulez, comme des tests individuels.
Dans mon exemple, j'ai un appui fichier appelé TestList.csv, qui est copié à la sortie. Il ressemble à ceci:
Vos tests seront exécutés dans l'ordre que vous avez spécifié, et en normal test d'isolement (c'est à dire si l'un tombe en panne, le reste encore exécuté, mais le partage des classes statiques).
Ci-dessus est vraiment l'idée de base, si je devais l'utiliser dans la production, je voudrais générer le test des noms de fonction et de leur ordre dynamiquement avant l'exécution du test. Peut-être en tirant parti de PriorityAttribute que vous avez trouvé et un simple code de réflexion pour extraire les méthodes d'essai de la classe et de leur ordonner de manière appropriée, puis d'écrire que pour la source de données.
Ici est une classe qui peut être utilisé pour configurer et exécuter commandé des tests indépendants de MS Commandé des Tests cadre pour quelque raison que ce soit, comme de ne pas avoir à ajuster mstest.exe arguments sur une machine de compilation, ou le mélange de commander les non-ordonné dans une classe.
L'original framework de test ne voit que la liste de commandé des tests comme un seul test de sorte que toute init/nettoyage comme [TestInitalize()] Init() est appelée avant et après l'ensemble.
Utilisation:
Mise en œuvre:
Je ne vais pas traiter la commande de tests, désolé. D'autres l'a déjà fait. Aussi, si vous savez à propos de "commandé des tests" - eh bien, c'est MS VS la réponse au problème. Je sais que ceux commandés-tests ne sont pas fun. Mais ils ont pensé qu'il sera "il" et il n'y a vraiment rien de plus à MSTest à ce sujet.
Je vous écris à propos d'une de vos hypothèses:
À moins que votre classe statique représente un processus à l'échelle extérieure de l'état à l'extérieur de votre code (ie. l'état de non géré native de la bibliothèque DLL thats P/Invoquée par le reste de votre code), votre hypothèse que
there is no way
n'est pas vrai.Si votre classe statique qui se réfère à cela, alors, désolé, vous avez parfaitement raison, le reste de cette réponse n'est pas pertinente. Encore, que vous ne le dis pas, je suppose que votre code est "géré".
De penser et de vérifier la
AppDomain
truc. Rarement il faut, mais c'est exactement le cas lorsque vous auriez probablement comme pour les utiliser.Vous pouvez créer un nouveau domaine d'application, et d'instancier le test il y a, et exécutez le test de la méthode. Statique des données utilisées par le code managé sera isolé là et à la fin, vous serez en mesure de décharger le domaine d'application et toutes les données, statistiques, inclus, va s'évaporer. Puis, ensuite, le test d'initialiser un autre domaine d'application, et ainsi de suite.
Cela va fonctionner, sauf si vous avez extérieure de l'état que vous devez suivre. Domaines d'application seulement d'isoler la gestion de la mémoire. Toutes les DLL native sera toujours en charge par processus et de leur état sera partagé par tous les domaines d'application.
Également de créer ou de démolir les domaines d'application vont, ainsi, de ralentir les tests. Aussi, vous pouvez avoir des problèmes avec la résolution de l'assemblée dans l'appdomain enfant, mais ils peuvent être résolus avec une quantité raisonnable de code réutilisable.
Aussi, vous pouvez avoir les petits problèmes de la transmission des données de test pour - de - l'enfant du domaine d'application. Objets passés devront être soit sérialisable, d'une certaine façon, ou être
MarshalByRef
ou etc. En parlant de la croix-domaine est presque comme de la CIB.Cependant, prendre soin ici, ce sera 100% réussi à parler. Si vous prenez des soins supplémentaires et ajouter un peu de travail pour le domaine d'application de configuration, vous pourrez même passer des délégués et de les exécuter dans le domaine cible. Alors, au lieu de faire quelques poilus de la croix-domaine de l'installation, vous pouvez envelopper vos tests avec quelque chose comme:
ou même
si votre test framework prend en charge la création de ces wrappers/extensions. Après quelques recherches et de travail, leur utilisation est presque banal.
Je vois que ce sujet est de près de 6 ans, et nous avons maintenant la nouvelle version de Visual studio, mais je vais répondre quand même.
J'ai eu ce problème de commande de Visual Studio 19 et j'ai pensé à elle en ajoutant lettre capitale (vous pouvez également ajouter des petits lettre) en face de votre nom de la méthode et dans l'ordre alphabétique comme ceci:
Et ainsi de suite.
Je sais que cela n'a pas l'air attrayant, mais il semble que Visual est le tri de vos tests dans l'explorateur de tests dans l'ordre alphabétique, n'a pas d'importance comment vous l'écrivez dans votre code.
Liste de lecture ne fonctionne pas pour moi dans ce cas.
Espère que cela aidera.
Vous pouvez nommer les espaces de noms et les classes dans l'ordre alphabétique. ex.:
où
MyApp.Test.Stage01_Setup
est un espace de noms etStep01_BuildDB
est un nom de classe.