16

I have a unit test that tests if an Exception is throw, but this Exception is only throw in Debug mode (via the [Conditional("DEBUG")] Attribute). If I run this test in Release mode, it fails. I tried to apply the same Attribute on the test but it's no taken into account.

How can I exclude a test in Release mode? Does it even make sense to run unit tests in Release mode or should I stick to Debug mode?

Julien Poulin
  • 12,737
  • 10
  • 51
  • 76

5 Answers5

17

As for most of your question, it depends somewhat on what unit testing tool your using. However, in general what you want are preprocessor directives

//C#
#ifndef DEBUG
    //Unit test
#endif

Perhaps for your situation

//C# - for NUnit
#if !DEBUG
    [Ignore("This test runs only in debug")] 
#endif 

But as to whether to leave unit tests in the release version? I'd give a resounding NO. I'd suggest moving all your unit tests into it's own project and NOT including this in your releases.

Kobi
  • 135,331
  • 41
  • 252
  • 292
C. Ross
  • 31,137
  • 42
  • 147
  • 238
  • Of course, all my unit tests are in another project, but I can still run them in Release mode... – Julien Poulin Oct 30 '09 at 11:51
  • Why would you really want them to be different in release and debug? – C. Ross Oct 30 '09 at 12:36
  • I want to be sure that me code will behave the same in Debug and in Release mode. But in this particular case, I *know* that the test will fail in Release mode since the Exception should only be thrown in Debug mode (by design) – Julien Poulin Oct 30 '09 at 13:23
  • Well, I came up with a possible solution, provided your using NUnit. – C. Ross Oct 30 '09 at 13:49
  • I ended up using your solution after all. Since I'm using MSTest, the Attribute is [Ignore] (no parameter). – Julien Poulin Oct 30 '09 at 15:08
  • This is a better solution that works in every environment: http://stackoverflow.com/questions/5805464/are-there-nunit-test-case-attributes-for-specifying-configuration Just make a "DebugOnly" Category and exclude that from your Release build – Scott Oct 17 '12 at 17:24
7

Try this:

#if DEBUG

// here is your test

#endif
Stefan Steinegger
  • 63,782
  • 15
  • 129
  • 193
  • 1
    This works but I think it's a too drastic solution. Instead, I used the [Ignore] Attribute (still, it's enclosed inside a #if !DEBUG ... #endif, but I like it better). – Julien Poulin Oct 30 '09 at 15:12
6

If you're using NUnit, you can make your unit test methods conditional:

[System.Diagnostics.Conditional("DEBUG")]
public void UnitTestMethod()
{
   // Tests here
}

This way it will only be executed in DEBUG builds. I don't have a lot of experience with Visual Studio unit tests, but I'm pretty sure that this should work there in VS too.

EDIT: Others have mentionned conditional compilation directives. I don't think that it is a very good idea, for a number of reasons. To learn more about the differences between conditional compilation directives and the conditional attribute, read Eric Lippert's excellent article here.

Tamas Czinege
  • 118,853
  • 40
  • 150
  • 176
  • 2
    I'm using MSTest and it looks like the Conditional Attribute is not honored by the test engine... – Julien Poulin Oct 30 '09 at 12:01
  • You could put the conditional attribute on a DoUnitTestMethod helper method, which you would call from UnitTestMethod. This would then become an empty test that always passes in Release mode. Gets trickier with things like [ExpectedException] though. Simplest just to use #if DEBUG around the whole test case. – yoyo Jul 08 '14 at 23:44
5

If you're using XUnit, you can use the following method as described by Jimmy Bogard by extending the fact attribute:

public class RunnableInDebugOnlyAttribute : FactAttribute
{
    public RunnableInDebugOnlyAttribute()
    {
        if (!Debugger.IsAttached)
        {
            Skip = "Only running in interactive mode.";
        }
    }
}

and then you can use this as follows:

[RunnableInDebugOnly]
public void Test_RunOnlyWhenDebugging()
{
    //your test code
}
Thomas Mulder
  • 740
  • 10
  • 26
1

Similar solution for NUnit framework(only debugging test works):

public class DebugOnlyAttribute : NUnitAttribute, IApplyToTest
{

    private const string _reason = "Debug only";

    public void ApplyToTest(Test test)
    {
        if (!Debugger.IsAttached)
        {
            test.RunState = RunState.Ignored;
            test.Properties.Set(PropertyNames.SkipReason, _reason);
        }

    }
}

[DebugOnly]
[Test]
public void TestMethod()
{ 
//your test code
}