Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a TestActionAttribute in NUnit run BeforeTest before the fixture's own SetUp method?

Tags:

mbunit

nunit

I have some old MbUnit code which looks like this:

public class MyFixture {

    [SetUp]
    public void SetUp() {
        // Add data to database
    }

    [Test, Rollback]
    public void DoTest() {
        // Tests with the data
    }
}

My new NUnit Rollback attribute looks a bit like this:

public class RollbackAttribute : TestActionAttribute
{
    public override void BeforeTest(TestDetails testDetails)
    {
        // Begin transaction
    }

    public override void AfterTest(TestDetails testDetails)
    {
        // Abort transaction
    }
}

The Rollback should roll back the new data added in the SetUp method as well as any modifications during the test itself. Unfortunately, it seems that NUnit's BeforeTest runs after the fixture's SetUp method, so the data added during SetUp is not rolled back.

Is there a way to run BeforeTest before SetUp?

One option would be a base class, and replace the existing Rollback attributes with additional code in SetUp and TearDown, however some of my tests require running outside a transaction (they create multiple transactions themselves during the test run), so adding transactions around all test cases would require a bit of care. I'd rather find a solution which can re-use the existing Rollback attributes.

like image 849
Douglas Avatar asked Jul 10 '15 13:07

Douglas


1 Answers

Is there a way to run BeforeTest before SetUp?

I don't think so, see e.g. this related discussion on google groups. Issue being discussed there is very similar, as you can see, code in SetUp method would run even prior to BeforeTest method used on test fixture level (you have it on test level).

Workaround from my point of view would be to remove the SetUpAttribute from the SetUp method and call the SetUp method explicitly at the beginning of the each test, i.e.:

public class MyFixture
{
    public void SetUp()
    {
        // Add data to database
    }

    [Test, Rollback]
    public void DoTest()
    {
        SetUp();

        // Tests with the data
    }
}

Your question also reminded me of question that marc_s raised in this SO thread. Question is unrelated to your problem, but he used the same construct as I am proposing above so it is perhaps not that bad idea.

EDIT:

Here is an opened issue on NUnit's github. But still, requested order there is:

BeforeTest (BaseFixture)
BaseSetUp BeforeTest (Fixture)
SetUp
BeforeTest (Test)
Test AfterTest (Test)
TearDown AfterTest (Fixture)
BaseTearDown AfterTest (BaseFixture)

So not exactly what you desire, "BeforeTest (Test)" would be executed after SetUp.

like image 174
Michal Hosala Avatar answered Sep 28 '22 00:09

Michal Hosala