Search code examples
c#nunitnunit-3.0

Ignoring (skipping) an NUnit test case without throwing an exception


I have a requirement to not run a test case during certain times in the month and I would like to ignore or skip the relevant test(s) when applicable. So far the only attribute I have found that makes sense is Assert.Ignore();. Unfortunately triggering this method throws an IgnoreException and as a consequence the NUnit TearDown will not be triggered. This is not ideal as I have code that I would like to execute after each test case irrespective of the test outcome. I was incorrect in my assumption please find comments below...

In an ideal world I wish I could just set the test outcome in my ignore / skipped part of the code, example:

else
{
    //it's after the 25th of the month let's skip this test case
    TestContext.CurrentContext.Result.Outcome == ResultState.Ignored;
}

But I understand that TestContext.CurrentContext.Result.Outcome is only a Get for good reason and it would most likely just open a can of worms with people just setting their tests as passed when they should not etc..

[Test]
[TestCase(TestName = "Test A")]
[Description("Test A will be testing something.")]
[Category("Regression Test Pack")]
public void Test_Case_1()
{
    sessionVariables = new Session().SetupSession(uiTestCase: true);

    if (DateTime.Now.Day <= 25)
    {
        //let's test something!
    }
    else
    {
        //it's after the 25th of the month let's skip this test case
        Assert.Ignore();
    }
}

[TearDown]
public void Cleanup()
{
    sessionVariables.TeardownLogic(sessionVariables);
}

Solution

  • As you discovered, use of Assert.Ignore does not cause the teardown to be skipped. (If it did, that would be an NUnit bug, because teardown must always be run if setup has been run)

    So, your choice of how to end the test depends on how you want the result to be shown...

    • Simply returning causes the test to pass, without any special message.

    • Assert.Pass does the same thing but allows you to include a message.

    • Assert.Ignore issues an "ignored" warning and allows you to specify a reason. The warning is propagated so that the result of the run as a whole is also "Warning".

    • Assert.Inconclusive gives an "inconclusive" result, which is intended to mean that the test could not be run due to some external factor. You may also specify the specific reason and the overall run result is not affected.

    • As an alternative to Assert.Inconclusive, you could use Assume.That with an appropriate test. For example, the following code would trigger the "inconclusive" result after the 25th of the month:

        Assume.That(DateTime.Now.Day <= 25);
    

    For what it's worth, the "Inconclusive" result is intended for exactly this kind of situation. It means that the test could not be run for reasons beyond it's control. "Ignored" results are intended to be treated as a problem to eventually be solved by the team, although many folks use it differently.

    From the point of view of NUnit's design, Assume.That is the most natural way to produce the result. You would normally place it at the beginning of the test or the SetUp method, before any other code.