The real difference between NUnit and XUnit

I’ve just started yet another pet project and wanted to pick a unit testing framework (.NET). On a soon-to-regret whim I’m tried googling “NUnit vs. XUnit” and read the first 10 posts I got. They were informative and mostly correct, unfortunately all completely missed the one big difference between those two excellent unit testing frameworks…
Consider the following two test Fixtures
NUnit
[TestFixture]
public class NUnitTwoTests
{
    private int _myInt = 0;

    [Test]
    public void Test1()
    {
        _myInt++;

        Assert.That(_myInt, Is.EqualTo(1));
    }

    [Test]
    public void Test2()
    {
        _myInt++;

        Assert.That(_myInt, Is.EqualTo(1));
    }
}
XUnit
public class XUnitTwoTests
{
    private int _myInt = 0;

    [Fact]
    public void Test1()
    {
        _myInt++;

        Assert.Equal(1, _myInt);
    }

    [Fact]
    public void Test2()
    {
        _myInt++;

        Assert.Equal(1, _myInt);
    }
}
Both looks almost the same and yet if you run them you’ll notice that they are in fact quite different:
image

The same result will happen regardless of unit test runner used – you can try using Visual Studio or command line – the only change will be which of the two NUnit test fails – depending on which test run first.
The reason that one of NUnit tests failed is that NUnit runs all of the tests in the same Fixture (a.k.a class) using the same instance while XUnit start a new instance per test. Which means that if you have fields (just like _myInt) in your tests they may cause problems in other tests due to shared state – also please don’t have fields in your unit tests – ever!
Running each test as a separate instance makes sure (read: reduces the chance) that one test will cause other test to fail. Although you can always prevent shared state in tests using other methods and tools it is another layer of isolation.
Does it mean that you should use XUnit and not NUnit – that’s up to you (I use both).
Can you guess how does Microsoft’s MSTest behaves? try the same experiment and find out.

Until then – happy coding…

Labels: , , ,