158 votes

Déterminer si le code est en cours d'exécution dans le cadre d'un test unitaire

J'ai une unité de test (nUnit). De nombreuses couches en bas de la pile d'appel d'une méthode ne fonctionnera pas s'il est en cours d'exécution par l'intermédiaire d'une unité de test.

L'idéal serait d'utiliser quelque chose comme se moquer de configuration de l'objet que cette méthode est selon, mais c'est la 3ème partie du code et je ne peux pas le faire sans beaucoup de travail.

Je ne veux pas d'installation de nUnit méthodes spécifiques - il y a trop de niveaux ici, et c'est une mauvaise façon de faire de test de l'unité.

Au lieu de ce que je voudrais faire est d'ajouter quelque chose comme cela, profondément vers le bas dans la pile d'appel

#IF DEBUG // Unit tests only included in debug build
if (IsRunningInUnitTest)
   {
   // Do some setup to avoid error
   }
#endif

Ainsi, toutes les idées sur la façon d'écrire IsRunningInUnitTest?

P. S. je suis pleinement conscient que ce n'est pas super design, mais je pense que son meilleur que les solutions de rechange.

110voto

Jon Skeet Points 692016

Je l'ai déjà fait auparavant - je devais me tenir le nez pendant que je le faisais, mais je l'ai fait. Le pragmatisme bat le dogmatisme à chaque fois. Bien sûr, s'il y a une bonne façon , vous pouvez factoriser pour l' éviter, ce serait formidable.

En gros, j'avais une classe "UnitTestDetector" qui vérifiait si l'assembly de la structure NUnit était chargé dans le AppDomain actuel. Il suffit de faire cela une fois, puis de mettre en cache le résultat. Moche, mais simple et efficace.

96voto

Ryan Points 11565

En prenant l’idée de Jon, c’est ce que j’ai trouvé -

 using System;
using System.Reflection;

/// <summary>
/// Detect if we are running as part of a nUnit unit test.
/// This is DIRTY and should only be used if absolutely necessary 
/// as its usually a sign of bad design.
/// </summary>    
static class UnitTestDetector
{

    private static bool _runningFromNUnit = false;      

    static UnitTestDetector()
    {
        foreach (Assembly assem in AppDomain.CurrentDomain.GetAssemblies())
        {
            // Can't do something like this as it will load the nUnit assembly
            // if (assem == typeof(NUnit.Framework.Assert))

            if (assem.FullName.ToLowerInvariant().StartsWith("nunit.framework"))
            {
                _runningFromNUnit = true;
                break;
            }
        }
    }

    static bool IsRunningFromNunit
    {
        get { return _runningFromNUnit; }
    }
}
 

Tuyautez à l'arrière, nous sommes tous assez grands pour reconnaître que nous faisons quelque chose que nous ne devrions probablement pas;)

71voto

Dangph Points 5561

Adapté de la réponse de Ryan. Celui-ci est destiné au framework de test unitaire MS.

La raison pour laquelle j'ai besoin de cela est parce que je montre un MessageBox sur des erreurs. Mais mes tests unitaires testent également le code de traitement des erreurs et je ne souhaite pas qu'un MessageBox apparaisse lors de l'exécution des tests unitaires.

 /// <summary>
/// Detects if we are running inside a unit test.
/// </summary>
public static class UnitTestDetector
{
    static UnitTestDetector()
    {
        string testAssemblyName = "Microsoft.VisualStudio.QualityTools.UnitTestFramework";
        UnitTestDetector.IsInUnitTest = AppDomain.CurrentDomain.GetAssemblies()
            .Any(a => a.FullName.StartsWith(testAssemblyName));
    }

    public static bool IsInUnitTest { get; private set; }
}
 

Et voici un test unitaire pour cela:

     [TestMethod]
    public void IsInUnitTest()
    {
        Assert.IsTrue(UnitTestDetector.IsInUnitTest, 
            "Should detect that we are running inside a unit test."); // lol
    }
 

16voto

Kiquenet Points 2772

Peut-être utile, vérifier le ProcessName actuel:

 public static bool UnitTestMode
{
    //C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\QTAgent32.exe: QTAgent32.exe
    // C:\PROGRAM FILES (X86)\MICROSOFT VISUAL STUDIO 11.0\COMMON7\IDE\COMMONEXTENSIONS\MICROSOFT\TESTWINDOW\vstest.executionengine.x86.exe
    get 
    { 
        return (System.Diagnostics.Process.GetCurrentProcess().ProcessName == "VSTestHost")
                    || (System.Diagnostics.Process.GetCurrentProcess().ProcessName == "vstest.executionengine.x86")
                    || (System.Diagnostics.Process.GetCurrentProcess().ProcessName == "QTAgent32")
                    ; 
    }
}
 

Références:
Matthew Watson dans http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/11e68468-c95e-4c43-b02b-7045a52b407e/

13voto

Eric Bole-Feysot Points 558

Assembly.GetEntryAssembly () semble être null en mode test.

 #IF DEBUG // Unit tests only included in debug build 
  if (Assembly.GetEntryAssembly() == null)    
  {
    // Do some setup to avoid error    
  }
#endif 
 

Notez que si Assembly.GetEntryAssembly () est null, Assembly.GetExecutingAssembly () ne l’est pas.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X