82

The NUnit documentation doesn't tell me when to use a method with a TestFixtureSetup and when to do the setup in the constructor.

public class MyTest
{
    private MyClass myClass;

    public MyTest()
    {
        myClass = new MyClass();
    }

    [TestFixtureSetUp]
    public void Init()
    {
        myClass = new MyClass();
    }
}

Are there any good/bad practices about the TestFixtureSetup versus default constructor or isn't there any difference?

abatishchev
  • 98,240
  • 88
  • 296
  • 433
Paco
  • 8,335
  • 3
  • 30
  • 41
  • As this is always a frequent question being asked, consider [this](https://stackoverflow.com/a/4970076/908336) and [this](https://stackoverflow.com/a/8689398/908336) (the same discussions for `MSTest`). But beware of the side effects of fixture setups on test readability (look [here](http://jamesnewkirk.typepad.com/posts/2007/09/why-you-should-.html) and [here](https://lostechies.com/jimmybogard/2013/09/26/test-styles-and-avoiding-setupteardown/)). – Masood Khaari Oct 22 '15 at 08:33
  • Just my 1 cent: This is useful when having a base class for many tests. Derived classes automatically will run the TestFixtureSetup defined in the parent class. You can't do that with constructors unless you call them specifically (this might or might not be an issue, depending of how many derived classes you have) – Nelson Rodriguez May 31 '18 at 14:11

10 Answers10

64

Why would you need to use a constructor in your test classes?

I use [SetUp] and [TearDown] marked methods for code to be executed before and after each test, and similarly [TestFixtureSetUp] and [TestFixtureTearDown] marked methods for code to be executed only once before and after all test in the fixture have been run.

I guess you could probably substitute the [TestFixtureSetUp] for a constructor (although I haven't tried), but this only seems to break from the clear convention that the marked methods provide.

Richard Ev
  • 52,939
  • 59
  • 191
  • 278
Sam Wessel
  • 8,830
  • 8
  • 40
  • 44
  • 5
    I had no idea why I need a constructor, but I have also no idea why I need a TestFixtureSetUp. I know about the setup, teardown, and testfixtureteardown attributes. I just don't know the difference between the constructor and testfixturesetup attribute. – Paco Oct 17 '08 at 16:06
  • 5
    Just to answer your question. You need to use a constructor in your test classes if you have parametrized test fixtures. – oderibas Jan 16 '13 at 09:16
22

I think this has been one of the issues that hasn't been addressed by the nUnit team. However, there is the excellent xUnit project that saw this exact issue and decided that constructors were a good thing to use on test fixture initialization.

For nunit, my best practice in this case has been to use the TestFixtureSetUp, TestFixtureTearDown, SetUp, and TearDown methods as described in the documentation.

I think it also helps me when I don't think of an nUnit test fixture as a normal class, even though you are defining it with that construct. I think of them as fixtures, and that gets me over the mental hurdle and allows me to overlook this issue.

Richard Ev
  • 52,939
  • 59
  • 191
  • 278
casademora
  • 67,775
  • 17
  • 69
  • 78
  • 2
    Please note the [xUnit article](https://xunit.github.io/docs/comparisons.html) is suggesting that `Setup`s (as well as constructors) are generally a bad idea that makes test code [difficult to follow](http://jamesnewkirk.typepad.com/posts/2007/09/why-you-should-.html), NOT that constructors are better than the `Setup`s. Parameterless constructors however are the last resort for those who really need it. Also see this: [Test styles and avoiding setup/teardown](https://lostechies.com/jimmybogard/2013/09/26/test-styles-and-avoiding-setupteardown/) – Masood Khaari Oct 22 '15 at 08:20
13

One thing you can't do with [TestFixtureSetup] that you can do in the constructor is receive parameters from the [TestFixture] .

If you want to parameterise your test fixture, then you will have to use the constructor for at least some of the set-up. So far, I've only used this for integration tests, e.g. for testing a data access layer with multiple data providers:

[TestFixture("System.Data.SqlClient",
  "Server=(local)\\SQLEXPRESS;Initial Catalog=MyTestDatabase;Integrated Security=True;Pooling=False"))]
[TestFixture("System.Data.SQLite", "Data Source=MyTestDatabase.s3db")])]
internal class MyDataAccessLayerIntegrationTests
{
    MyDataAccessLayerIntegrationTests(
        string dataProvider,
        string connectionString)
    {
        ...
    }
}
Ergwun
  • 12,579
  • 7
  • 56
  • 83
13

I have often wondered what the need for [TestFixtureSetUp] was, given that there is a simple, well understood first class language construct that does exactly the same thing.

My preference is to use constructors, to take advantage of the readonly keyword ensuring member variables cannot be reinitialised.

Richard Ev
  • 52,939
  • 59
  • 191
  • 278
  • 4
    The readonly keyword does not ensure that a member does not get modified. If the member is a class, the internal state of the class can be modified in a test, and this state will be carried over to the next test method (because nunit does not recreate the class between each test run) – Pete Nov 11 '09 at 14:47
12

There is difference between constructor and method marked with [TestFixtureSetUp] attribute. According to NUnit documentation:

It is advisable that the constructor not have any side effects, since NUnit may construct the object multiple times in the course of a session.

So if you have any expensive initialization it is better to use TestFixtureSetUp.

Richard Ev
  • 52,939
  • 59
  • 191
  • 278
oderibas
  • 1,575
  • 12
  • 20
  • 1
    This is assuming that the method marked TestFixtureSetUp is static. Otherwise it would be impossible for the constructor to be called more often unless the test instance is being thrown away without being used by NUnit which I would doubt. – jpierson Jul 31 '14 at 07:03
3

[TestFixtureSetUp] and [TestFixtureTearDown] are for whole test class. runs only once.

[SetUp] and [TearDown] are for every test method(test). runs for every test.

M4ver1k
  • 1,505
  • 1
  • 15
  • 26
Shankar S
  • 387
  • 5
  • 13
3

An important difference between constructor and TestFixtureSetUp is that, in NUnit 2 at least, constructor code is actually executed on test enumeration, not just test running, so basically you want to limit ctor code to only populating readonly, i.e. parameter, values. Anything that causes side-effects or does any actual work needs to either be wrapped in a Lazy or done in the TestFixtureSetUp / OneTimeSetUp. So, you can think of the constructor as solely a place to configure the test. Whereas the TestFixtureSetUp is where the test fixture, the required initial state of the system before tests are run, is initialized.

Novaterata
  • 4,356
  • 3
  • 29
  • 51
2

I think I have a negative good answer - the reason to use a constructor instead of the attribute is when you have an inheritence between test classes.

Only one method annotated with [TestFixtureSetup] will be called (on the concrete class only), but the other fixture initializers will not. In this case I'd rather put the initialization in the constructor, which has a well-defined semantics for inheritance :)

Richard Ev
  • 52,939
  • 59
  • 191
  • 278
ripper234
  • 222,824
  • 274
  • 634
  • 905
  • 2
    This has changed since NUnit 2.5 Now all methods annotated with [TestFixtureSetup] will be called. – oderibas Jan 16 '13 at 09:19
-1

The method with [SetUp] may be async. The constructor can not be.

RM.
  • 1,984
  • 19
  • 29
-2

The constructor and the SetUp methods are used differently:
The constructor is run only once.
However, the SetUp methods are run multiple times, before every test case is executed.

Be Brave Be Like Ukraine
  • 7,596
  • 3
  • 42
  • 66