Run tests explicitly in xUnit.net

I’ve more or less ditched NUnit as my default automated testing platform in .NET, preferring the more sensible defaults of xUnit.net. Switching wasn’t so bad – it mostly involved moving setup/teardown methods to constructors/Dispose methods. One piece that was missing was the ability to have explicit tests. Those are tests that are run only if I explicitly select them to run in the UI (using ReSharper, TestDriven.NET etc.), but won’t run if part of an entire test suite.

NUnit also has the concept of an Ignore attribute, which skips a test. xUnit does support this, along with most other NUnit concepts, but not the ExplicitAttribute. Unfortunately, NUnit has this baked in to its framework. What I’d like to do is skip tests only when explicitly run inside Visual Studio, and not run when part of my local build or CI build.

The most consistent way I’ve found to do so is to skip the tests only when a debugger is not attached. I can’t do things like when the process is launched by a certain host or in a certain folder – that’s too brittle. Luckily, xUnit is easily extensible in this way, so we can create a Fact attribute that only works if a debugger is attached:

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

Inside my test that I only want to run explicitly from an attached debugger, I replace the Fact attribute with one I created above. In my case, I’m wiping a database conditionally:

public class SchemaCreationTest
{
    [RunnableInDebugOnly]
    public void Wipe_Database()
    {
        var configuration = new ConfigurationFactory().CreateConfiguration();
        var schemaExport = new SchemaExport(configuration);

        schemaExport.Execute(false, true, false);

    }
}

If I run this test through the IDE, it gets skipped. If I run it through the automated build, it gets skipped. If I run the test with an attached debugger, it does run. Not exactly the behavior we had with NUnit, but close enough!

Related Articles:

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Jimmy Bogard

I'm a technical architect with Headspring in Austin, TX. I focus on DDD, distributed systems, and any other acronym-centric design/architecture/methodology. I created AutoMapper and am a co-author of the ASP.NET MVC in Action books.
This entry was posted in Testing. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Robert R.

    Curious why testing the host is brittle – doesn’t VS always run your app with AppName.vshost.exe?

    • jbogard

      The test runners don’t, unfortunately.

      • Azzabi Ahmed

        Hi jimmy thank you for your post !! but what made you switch to xunit at first place if you like the functionality on nunit and nothing xunit can do that nunit dont !! im seeing this switch as yagni and im curious to know the reasons to change something that you are familiar with and no problem with it to another one that doesnt add anything !! am i wrong ? thanks

        • jbogard

          There are a couple of things – one, xUnit is a lot more extensible, so that I can customize behavior quite a bit. The other is that the rules for lifecycle of tests were more straightforward – no Setup/Teardown methods.
          NUnit isn’t bad – I just found myself preferring a model that matches C# style more

    • http://blog.decayingcode.com/ Maxime Rouiller

      To add on what Jimmy said, not everyone uses VS for running tests. What if I use ReSharper? NCrunch? MightyMoose? TestDriven.NET? The runner (and thus the host) will change. Whether a debugger is attached or not is more precise.

  • http://www.aquabirdconsulting.com/ Khalid Abuhakmeh

    That is pretty slick, I like it! This would be great for helper tests to get devs up and running with your code base.

  • Pingback: The Morning Brew - Chris Alcock » The Morning Brew #1382

  • Chris Tavares

    Ok, this has to be a first – your Gists only show in IE10, not in Firefox or Chrome.

  • Ben

    I find NUnit’s action attributes a great extensibility point and have moved away from a lot repetitive setup/teardown or awkward inheritance hierarchies.

  • Cristi Lupascu

    Thanks for the tip! Here’s another way of defining this attribute that avoids the ‘Virtual member call in constructor’: https://gist.github.com/clupascu/6181793

  • http://www.Marisic.Net/ dotnetchris

    CUE THE EVIL

    public override string Skip
    {
    get {
    if (Debugger.IsAttached.Equals(false)) return “Only running in interactive mode.;

    return MessageBox.Show(ConfirmDialog, “Cancel to exit”, MessageBoxButtons.OKCancel) == DialogResult.OK
    ? null
    : ConfirmDialog + ” CANCELED”;
    }
    set { }
    }