J'ai un test unitaire (nUnit). De nombreuses couches dans la pile d'appels, une méthode échouera si elle s'exécute via un test unitaire.
Idéalement, vous utiliseriez quelque chose comme la moquerie pour configurer l'objet dont dépend cette méthode, mais il s'agit d'un code tiers et je ne peux pas le faire sans beaucoup de travail.
Je ne veux pas configurer des méthodes spécifiques à nUnit - il y a trop de niveaux ici et c'est une mauvaise façon de faire des tests unitaires.
Au lieu de cela, je voudrais ajouter quelque chose comme ça au plus profond de la pile d'appels
#IF DEBUG // Unit tests only included in debug build
if (IsRunningInUnitTest)
{
// Do some setup to avoid error
}
#endif
Alors des idées sur la façon d'écrire IsRunningInUnitTest?
PS Je suis pleinement conscient que ce n'est pas un design génial, mais je pense que c'est mieux que les alternatives.
c#
reflection
nunit
Ryan
la source
la source
Réponses:
Je l'ai déjà fait - j'ai dû me tenir le nez pendant que je le faisais, mais je l'ai fait. Le pragmatisme l'emporte à chaque fois sur le dogmatisme. Bien sûr, s'il est un moyen agréable , vous pouvez factoriser pour l' éviter, ce serait formidable.
Fondamentalement, j'avais une classe "UnitTestDetector" qui vérifiait si l'assembly du framework NUnit était chargé dans l'AppDomain actuel. Il ne fallait le faire qu'une seule fois, puis mettre en cache le résultat. Moche, mais simple et efficace.
la source
AppDomain.GetAssemblies
et vérifier l'assemblage pertinent - pour MSTest, vous devez regarder quels assemblages sont chargés. Regardez la réponse de Ryan pour un exemple.En prenant l'idée de Jon, c'est ce que j'ai trouvé -
À l'arrière, nous sommes tous assez grands pour reconnaître quand nous faisons quelque chose que nous ne devrions probablement pas;)
la source
Adapté de la réponse de Ryan. Celui-ci est pour le cadre de test unitaire MS.
La raison pour laquelle j'en ai besoin est que je montre une MessageBox sur les erreurs. Mais mes tests unitaires testent également le code de gestion des erreurs, et je ne veux pas qu'un MessageBox apparaisse lors de l'exécution des tests unitaires.
Et voici un test unitaire pour cela:
la source
Pour simplifier la solution de Ryan, vous pouvez simplement ajouter la propriété statique suivante à n'importe quelle classe:
la source
J'utilise une approche similaire à celle de tallseth
C'est le code de base qui pourrait être facilement modifié pour inclure la mise en cache. Une autre bonne idée serait d'ajouter un setter
IsRunningInUnitTest
et d'appelerUnitTestDetector.IsRunningInUnitTest = false
le point d'entrée principal de vos projets pour éviter l'exécution du code.la source
Peut-être utile, en vérifiant le ProcessName actuel:
Et cette fonction doit également être vérifiée par unittest:
Références:
Matthew Watson dans http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/11e68468-c95e-4c43-b02b-7045a52b407e/
la source
|| processName.StartsWith("testhost") // testhost.x86
pour VS 2019En mode test,
Assembly.GetEntryAssembly()
semble êtrenull
.Notez que si
Assembly.GetEntryAssembly()
c'estnull
,Assembly.GetExecutingAssembly()
non.La documentation dit: La
GetEntryAssembly
méthode peut être renvoyéenull
lorsqu'un assembly géré a été chargé à partir d'une application non gérée.la source
Quelque part dans le projet testé:
Quelque part dans votre projet de test unitaire:
Élégant, non. Mais simple et rapide.
AssemblyInitializer
est pour MS Test. Je m'attendrais à ce que d'autres cadres de test aient des équivalents.la source
IsRunningInUnitTest
n'est pas défini sur true dans ces AppDomains.Je l'utilise uniquement pour ignorer la logique qui désactive tous les TraceAppenders dans log4net au démarrage lorsqu'aucun débogueur n'est connecté. Cela permet aux tests unitaires de se connecter à la fenêtre de résultats Resharper même lorsqu'ils sont exécutés en mode non débogué.
La méthode qui utilise cette fonction est appelée soit au démarrage de l'application, soit au démarrage d'un appareil de test.
Il est similaire à l'article de Ryan mais utilise LINQ, supprime l'exigence System.Reflection, ne cache pas le résultat et est privé pour éviter toute utilisation abusive (accidentelle).
la source
Avoir une référence au framework nunit ne signifie pas que le test est en cours d'exécution. Par exemple, dans Unity, lorsque vous activez les tests de mode de lecture, les références de l'unité sont ajoutées au projet. Et lorsque vous exécutez un jeu, les références existent, donc UnitTestDetector ne fonctionnera pas correctement.
Au lieu de vérifier l'assemblage de nunit, nous pouvons demander à l'api de nunit de vérifier si le code est en cours d'exécution maintenant ou non.
Éditer:
Attention, le TestContext peut être généré automatiquement s'il est nécessaire.
la source
Utilisez simplement ceci:
En mode test, il retournera faux.
la source
J'étais mécontent d'avoir ce problème récemment. Je l'ai résolu d'une manière légèrement différente. Premièrement, je n'étais pas disposé à faire l'hypothèse que le framework nunit ne serait jamais chargé en dehors d'un environnement de test; J'étais particulièrement préoccupé par les développeurs exécutant l'application sur leurs machines. J'ai donc parcouru la pile d'appels à la place. Deuxièmement, j'ai pu supposer que le code de test ne serait jamais exécuté sur les binaires de publication, donc je me suis assuré que ce code n'existait pas dans un système de publication.
la source
fonctionne comme un charme
.
la source
Les tests unitaires ignoreront le point d'entrée de l'application. Au moins pour wpf, winforms et l'application console
main()
ne sont pas appelés.Si la méthode main est appelée, nous sommes en exécution , sinon nous sommes en mode test unitaire :
la source
Considérant que votre code est normalement exécuté dans le thread principal (gui) d'une application Windows Forms et que vous voulez qu'il se comporte différemment lors de l'exécution d'un test, vous pouvez vérifier
J'utilise ceci pour le code que je veux
fire and forgot
dans une application d'interface graphique, mais dans les tests unitaires, je pourrais avoir besoin du résultat calculé pour une assertion et je ne veux pas jouer avec plusieurs threads en cours d'exécution.Fonctionne pour MSTest. L'avantage est que mon code n'a pas besoin de vérifier le cadre de test lui-même et si j'ai vraiment besoin du comportement asynchrone dans un certain test, je peux définir mon propre SynchronizationContext.
Sachez que ce n'est pas une méthode fiable
Determine if code is running as part of a unit test
comme demandé par OP car le code peut s'exécuter dans un thread, mais pour certains scénarios, cela pourrait être une bonne solution (aussi: si je suis déjà en cours d'exécution à partir d'un thread d'arrière-plan, cela peut ne pas être nécessaire pour en créer un nouveau).la source
Application Le courant est nul lors de l'exécution sous le testeur d'unité. Au moins pour mon application WPF utilisant le testeur MS Unit. C'est un test facile à faire si nécessaire. Aussi, quelque chose à garder à l'esprit lorsque vous utilisez Application.Current dans votre code.
la source
J'ai utilisé ce qui suit dans VB dans mon code pour vérifier si nous sommes dans un test unitaire. spécifiquement, je ne voulais pas que le test ouvre Word
la source
Que diriez-vous d'utiliser la réflexion et quelque chose comme ça:
var underTest = Assembly.GetCallingAssembly ()! = typeof (MainForm) .Assembly;
L'assembly appelant sera l'endroit où se trouvent vos cas de test et remplacera simplement MainForm un type qui se trouve dans votre code en cours de test.
la source
Il existe également une solution très simple lorsque vous testez une classe ...
Donnez simplement à la classe que vous testez une propriété comme celle-ci:
Maintenant, votre test unitaire peut définir le booléen "thisIsUnitTest" sur true, donc dans le code que vous souhaitez ignorer, ajoutez:
C'est plus facile et plus rapide que d'inspecter les assemblages. Cela me rappelle Ruby On Rails où vous chercheriez si vous êtes dans l'environnement TEST.
la source