Skipping XUnit tests based on runtime conditions

Posted on Wednesday, 02 Jan 2019

Have you ever needed to skip a test under a certain condition? Say, the presence or absence of an environmental variable, or some conditional runtime check? No, me neither - that was up until recently.

Skipping tests is usually a good practice to get into, but I use the word "usually" here because as with all things in software there sometimes certain constraints or parameters that may well justify doing so. In my case I needed to skip a certain test if I was running on AppVeyor in Linux.

Having done a bit of digging I found two options that would work:

Option 1 - Using the #if preprocessor directive

Depending on your scenario it might be possible to simple use an #if preprocessor directive to include the test. If you're wishing to exclude a test based on the operating system the test were running on then this may be a solution.

#if IS_LINUX
[Fact]
public void ShouldlyApi()
{
    ...
}
#endif

My scenario also involved checking the presence of environmental variables, which I'd rather do through code. This led me to the next approach which I felt was more suitable.

Preferred Option - Leveraging existing XUnit functionality

XUnit already has the ability to skip a test by providing a reason for skipping the test in question via the Skip property that exists within the Fact attribute:

[Fact(Skip = "Doesn't work at the moment")]
public void ClassScenarioShouldFail()
{
    ...
}

So all we have to do is extend the FactAttribute class and set that property:

public sealed class IgnoreOnAppVeyorLinuxFact : FactAttribute
{
    public IgnoreOnAppVeyorLinuxFact() {
        if(RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && IsAppVeyor()) {
            Skip = "Ignore on Linux when run via AppVeyor";
        }
    }
    
    private static bool IsAppVeyor()
        => Environment.GetEnvironmentVariable("APPVEYOR") != null;
}

Now instead of using the traditional [Fact] attribute, we can use our new IgnoreOnAppVeyorLinuxFact attribute:

[IgnoreOnAppVeyorLinuxFact]
public void ShouldlyApi()
{
    ...
}
Back