5

I have a console application. In release environment, it works perfectly at this time. When in IDE debug environment, I don't want the console window close, so I added this function, and calling it in the very end of my program.

[Conditional("DEBUG")]
public static void DebugWaitAKey(string message = "Press any key")
{
    Console.WriteLine(message);
    Console.ReadKey();
}

It works well for me, when I debug my program. But with unit testing, it still wait for a key before exiting!

The work-around is only unit-testing release edition of my program, or test other functions. But I do want something can identify current session is under unit testing, and use that flag in this function.

Richard
  • 29,854
  • 11
  • 77
  • 120
Herbert Yu
  • 578
  • 6
  • 16

5 Answers5

5

I believe this should answer your question. I took a class from there and adapted it to your situation.

/// <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; }
}

Then I added a line to your method which if it is running a test it will not hit the Console.ReadKey();

[Conditional("DEBUG")]
public static void DebugWaitAKey(string message = "Press any key")
{
    Console.WriteLine(message);
    if(!UnitTestDetector.IsInUnitTest)
        Console.ReadKey();
}

Note: This would be considered a hack and would not be considered a best practice.

EDIT: I also created a sample project on github to demonstrate this code. https://github.com/jeffweiler8770/UnitTest

Community
  • 1
  • 1
jsw
  • 175
  • 3
  • 12
1

The simple way if your test runs from a dedicated UnitTest project : use a flag in AppSettings...

I would not investigate around patterns for such a purpose, i would run the test in a dedicated UnitTest project with its own configuration.

If you need to collect data maybe should you simply use traces (they can be customized from your .config file)... ?

Hope this helps...

Rénald
  • 1,412
  • 12
  • 29
1

I know this is old but I really don't like many of these answers, especially anything that hard codes an assembly name or version.

This works well, as long as the class you are testing is not Sealed. It's pretty simple:

Add this class variable to the class you are testing:

    protected Boolean IsInUnitTestMode = false;

We default it to false so in production it will always be false.

Add something like this wrapper to your test class

    class ProfileTest : Profiles
    {
        public ProfileTest() : base()
        {
            IsInUnitTestMode = true;
        }
    }

In this example Profiles is the class we are testing, ProfileTest is a wrapper class in the test project's namespace. It will never be deployed. The test class uses this to create an instance of the class to be tested:

    ProfileTest profiles = new ProfileTest();

As opposed to this:

    private Profiles profiles = new Profiles();

The we can use it something like this:

    private string ProfilePath
    {
         get
         {
            if (IsInUnitTestMode) 
                return SafeStorage.EnsureFolderExists(Path.Combine(SafeStorage.UserPath, UNITTESTFOLDERNAME)).FullName;
            else
                return SafeStorage.EnsureFolderExists(Path.Combine(SafeStorage.UserPath, PROFILEFOLDERNAME)).FullName;
            }
        }

As I said, this won't work with sealed classes, nor will it work well with static ones. With that said the number of times I actually choose to test for the unit test condition is quite rare. This works extremely well for me.

BigTFromAZ
  • 684
  • 7
  • 22
0

Rather than looking for whether the program was compiled in debug mode, you can look at whether a debugger is attached:

if (Debugger.IsAttached)
{
    Console.WriteLine(message);
    Console.ReadKey();
}

Note this will only detect if you start with F5 from Visual Studio, not Ctrl-F5 (i.e. Start with Debugging only)

Richard
  • 29,854
  • 11
  • 77
  • 120
  • [Conditional("DEBUG")] served the same purpose as your Debugger.IsAttached – Herbert Yu Apr 23 '15 at 22:29
  • No it wouldn't. The conditional attribute checks whether the program was compiled in debug mode (ie. the DEBUG symbol is present). Mine checks for whether a debugger is attached. – Richard Apr 24 '15 at 06:08
  • 1
    Admittedly mine will still pause if you debug your unit tests! But for normal running, this works fine. I use it in my programs simply because the console window closes by default if you use the debugger. – Richard Apr 24 '15 at 07:08
0

I used a variation of Jeff's UnitTestDetector. I did not want to check the unit test assembly and wanted to control which unit tests would consider this or not.

So I created a simple class with IsInUnitTest defaulting to false. Then in the unit test classes where I wanted the conditional code to run I added TestInitializer and TestCleanup where I set the bool accordingly.

Then in my regular code I can use UnitTestDetector.IsInUnitTest

Simple UnitTestDetector class:

/// <summary>
/// Detects if we are running inside a unit test.
/// </summary>
public static class UnitTestDetector
{
    static private bool _isInUnitTest = false;
    public static bool IsInUnitTest
    {
        get { return _isInUnitTest; }
        set { _isInUnitTest = value; }
    }
}

Unit Test to Test this stuff:

[TestClass]
public class UnitTestDetectorTest_WithoutIsInUnitTest
{
    [TestMethod]
    public void IsInUnitTest_WithoutUnitTestAttribute_False()
    {
        bool expected = false;
        bool actual = UnitTestDetector.IsInUnitTest;
        Assert.AreEqual(expected, actual);
    }
}

[TestClass]
public class UnitTestDetectorTest_WithIsInUnitTest
{
    [TestInitialize()]
    public void Initialize()
    {
        UnitTestDetector.IsInUnitTest = true;
    }

    [TestCleanup()]
    public void Cleanup()
    {
        UnitTestDetector.IsInUnitTest = false;
    }

    [TestMethod]
    public void IsInUnitTest_WithUnitTestAttribute_True()
    {
        bool expected = true;
        bool actual = UnitTestDetector.IsInUnitTest;
        Assert.AreEqual(expected, actual);
    }
}

Condition in Code:

if (UnitTestDetector.IsInUnitTest)
            return "Hey I'm in the unit test :)";
RitchieD
  • 1,831
  • 22
  • 21