Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Specflow with NUnit don't respect TestFixtureSetUpAttribute

I'm using SpecFlow with Nunit and I'm trying to setup my enviroment tests using TestFixtureSetUpAttribute, but it's never called.

I already tried to use MSTests and ClassInitialize attribute, but the same happen. The function isn't called.

Any ideas Why?

[Binding]
public class UsersCRUDSteps
{
    [NUnit.Framework.TestFixtureSetUpAttribute()]
    public virtual void TestInitialize()
    {
        // THIS FUNCTION IS NEVER CALLER

        ObjectFactory.Initialize(x =>
        {
            x.For<IDateTimeService>().Use<DateTimeService>();
        });

        throw new Exception("BBB");
    }

    private string username, password;

    [Given(@"I have entered username ""(.*)"" and password ""(.*)""")]
    public void GivenIHaveEnteredUsernameAndPassword(string username, string password)
    {
        this.username = username;
        this.password = password;
    }

    [When(@"I press register")]
    public void WhenIPressRegister()
    {
    }

    [Then(@"the result should be default account created")]
    public void ThenTheResultShouldBeDefaultAccountCreated()
    {
    }

Solution:

[Binding]
public class UsersCRUDSteps
{
    [BeforeFeature]
    public static void TestInitialize()
    {
        // THIS FUNCTION IS NEVER CALLER

        ObjectFactory.Initialize(x =>
        {
            x.For<IDateTimeService>().Use<DateTimeService>();
        });

        throw new Exception("BBB");
    }

    private string username, password;

    [Given(@"I have entered username ""(.*)"" and password ""(.*)""")]
    public void GivenIHaveEnteredUsernameAndPassword(string username, string password)
    {
        this.username = username;
        this.password = password;
    }

    [When(@"I press register")]
    public void WhenIPressRegister()
    {
    }

    [Then(@"the result should be default account created")]
    public void ThenTheResultShouldBeDefaultAccountCreated()
    {
    }
like image 247
muek Avatar asked Nov 01 '12 12:11

muek


Video Answer


1 Answers

Your TestInitialize is not called because it is inside your Steps class and not inside in an Unit Tests (because the actual unit test is inside the .cs which is generated from your .feature file).

SpecFlow has it's own test-lifetime events which are called hooks, these are all the predefined hooks:

  • [BeforeTestRun] / [AfterTestRun]
  • [BeforeFeature] / [AfterFeature]
  • [BeforeScenario] / [AfterScenario]
  • [BeforeScenarioBlock] / [AfterScenarioBlock]
  • [BeforeStep] / [AfterStep]

Note that this allows for greater flexibility in setup. For additional information see the documentation.

Based on the fact that you want to use the TestFixtureSetUp attribute you will probably need the BeforeFeature hook which will be called once before each feature, so you need to write:

[Binding]
public class UsersCRUDSteps
{
    [BeforeFeature]
    public static void TestInitialize()
    {               
        ObjectFactory.Initialize(x =>
        {
            x.For<IDateTimeService>().Use<DateTimeService>();
        });

        throw new Exception("BBB");
    }

    //...
}

Note that the [BeforeFeature] attribute needs a static method.

You should also note that if you are using the VS integration there is an project item type called SpecFlow Hooks (event bindings) which creates a binding class with some predefined hooks to help you get started.

like image 174
nemesv Avatar answered Oct 06 '22 08:10

nemesv