How to programmatically ignore some acceptance tests using TechTalk.SpecFlow and C#?

Dmytro picture Dmytro · Sep 25, 2012 · Viewed 9k times · Source

I have several feature files with some scenarios. I need to ignore several scenarios, or features, marked with some @tag depending on some condition. I have read specflow documentation but didn't find there something that can be useful for my solution. I want to use something like

[BeforeScenario("sometag")]
public static void BeforeScenario()
{
    if(IgnoreTests)
    {
       // This is the hot spot
       Scenario.DoSomethingToIgnoreScenarioIfConditionButRunScenarioIfConditionFalse();
    }        
}

Also I tried dynamically add or remove tags

[BeforeScenario("sometag")]
public static void BeforeScenario()
{
    if(IgnoreTests)
    {
       ScenarioContext.Current.ScenarioInfo.Tags.ToList().Add("ignore");
    }        
}

but it didn't work. Maybe is there some other way to dynamically add or remove tags? Or some methods in ScenarioContext class which will ignore current scenario?

Answer

nemesv picture nemesv · Sep 25, 2012

You have at least 3 options:

  1. Configure Specflow to treat pending steps as ignore with missingOrPendingStepsOutcome="Ignore" then you can write:

    if(IgnoreTests)
    {
        ScenarioContext.Current.Pending();
    } 
    

    It is maybe not what you want depending on your requirements for pending steps.

  2. Use your unit testing framework built in method to ignore the test during runtime. So if you are using e.g. NUnit then with the Assert.Ignore():

    if(IgnoreTests)
    {
        Assert.Ignore();
    }
    

    I think this is the cleanest/easiest solution.

  3. Or if you want do it a testing framework-agnostic way and you are not afraid to mess with Specflow internals then you can use the IUnitTestRuntimeProvider interface:

    if (IgnoreTests)
    {
        var unitTestRuntimeProvider = (IUnitTestRuntimeProvider) 
        ScenarioContext.Current
           .GetBindingInstance((typeof (IUnitTestRuntimeProvider))); 
        unitTestRuntimeProvider.TestIgnore("ignored");
    }
    

    This will work even if you change your unit testprovider but it's not guaranteed that this API won't break in future.