XUnit vs NUnit What to Choose to Write Clean Code Part 1.
Published: 2022-02-15 08:33:45


The question of which test framework to choose can appear for a new project or when the team decided to make an experiment trying to improve some internal problem. It’s well known for .net developers that there are three main frameworks: MSTest, NUnit, and XUnit. MSTest is out of scope for this article. I didn’t meet any project which uses it as a primary test framework. I certainly sure such projects exist, and it could be that developers from these projects have written a comprehensive guide щт why to choose MSTest.


![xunit vs nunit](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qshxm61p13w7iv9ktobh.png)

We’ll focus on two frameworks, NUnit and XUnit, and they are both quite good and provide common functionally to write tests. Firstly, we’ll look at each separately and then compare both functionalities.

## NUnit

> NUnit is a unit-testing framework for all .Net languages. Initially ported from JUnit

As it states on the landing page of [NUnit](https://nunit.org/).

We’ll cover the latest version of NUnit. At the moment when the article was written, it was 3.13.2. Execute the following commands to add NUnit for your test project:

```cs
dotnet add package NUnit --version 3.13.2
dotnet add package NUnit3TestAdapter --version 4.0.0
```

With these packages, you get an amazing variety of tools provided by NUnit as attributes. Let’s take a look at some of them, which definitely you need to know:


|name|description|
|----|----|
|TestFixture|	marks that class contains tests and allows to pass arguments into constructor|
|OneTimeSetUp|	allows to execute code once before all tests started|
|OneTimeTearDown|	it`s a pair to OneTimeTearDown gives us ability to clean resource when all tests finished|
|SetUp|	executes before each test|
|TearDown|	it`s a pair method to SetUp place where we can clean resources after test execution|
|Test|	allows to mark method as test which should be executed|
|TestCase|	gives ability to pass params to test and make it configurable|
|Ignore|	I hope you will not use it a lot. It skips test case during tests execution|
|Category|	define a category for test quite usefull when you need to run only specify category and not run all tests|
|Author|	this one as you can guess defines who wrote a test|
|MaxTime|	provides a way to setup max execution time for test|
|Description|	allows to add readable description to test|

It contains much more tools for developers and allows to configure tests for many scenarios.

Let’s check how it looks in code with all these attributes:

```cs
[Author("Andrew", "andrewkulta@akyltech.com")]
[TestFixture]
public class TestExample
{
    [OneTimeSetUp]
    public void OneTimeSetup()
    {
        Console.WriteLine("Setup just once");
    }

    [OneTimeTearDown]
    public void OneTimeTearDown()
    {
        Console.WriteLine("Teardown just once");
    }

    [SetUp]
    public void Setup()
    {
        Console.WriteLine("Setup before each test case");
    }

    [TearDown]
    public void TearDown()
    {
        Console.WriteLine("TearDOwn after each test");
    }

    [Test]
    [Description("")]
    [Author("AnotherAuthor")]
    public void Should_DoNothing()
    {
        Console.WriteLine("Sync test");
    }

    [Test]
    [Category("Async")]
    [MaxTime(100)]
    public async Task Should_DoNothingAsync()
    {
        Console.WriteLine("ASync test");
        await Task.Delay(200);
    }

    [TestCase(1)]
    [TestCase(2)]
    public void Should_BeCase(int param)
    {
        Console.WriteLine($"param is {param}");
    }

    [Ignore("example")]
    public void Should_BeIgnored()
    {
        Console.WriteLine("Never invoked");
    }
}
```

## XUnit is also known as xUnit.net

> xUnit.net is a free, open-source, community-focused unit testing tool for the .NET Framework

It was created with an idea to replace nUnit 2.* and 3.*. xUnit provides a set of tools to write clean and more independent tests.

List most used attributes from **xUnit**:

|name| description|
|----|----|
|Fact|	marks method as test and allows to configure custom name for method as well as timeout and skip reason.|
|Theory|	marks method as special type of test theory it means that this test is valid only with certain list of params|
|InlineDate|	allows to provide params for theory tests|
|Trait|	gives ability to setup custom metadata for test such as category or author etc...|

Let`s take a look at some examples for listed attributes:


```cs
public class xUnitExample : IDisposable
{
    public xUnitExample()
    {
        Console.WriteLine("Executes before each test as setup");
    }

    [Fact(DisplayName = "Test description")]
    [Trait("Category", "CustomCategory")]
    public void Should_BeATest()
    {
        Console.WriteLine("I`m a test");
    }

    [Fact(Timeout = 100)]
    public async Task Should_BeAsyncTest()
    {
        Console.WriteLine("I`m async test");
    }

    [Theory]
    [InlineData(1)]
    public void Should_BeTheory(int param)
    {
        Console.WriteLine($"param is {param}");
    }

    [Fact(Skip = "Ignore")]
    public void Should_BeSkipped()
    {
        Console.WriteLine("Should never be invoked");
    }

    public void Dispose()
    {
        Console.WriteLine("Executes after each test as teardown");
    }
}
```

As you can see, xUnit uses constructor and **IDisposable** pattern to implement setup and teardown. I faced developers who thought that xUnit requires implementing Destructor if you want to clear resources.

I think **NUnit** allows us to write more descriptive unit tests with various attributes for different purposes. But if you choose **xUnit** for your project, you get a cleaner code without all this mess with attributes. The final decision depends on your preferences, or maybe the team gets used to one of these frameworks.

## Conclusion

To be honest, it doesn’t matter which framework you will choose. They both provide a set of tools to write tests, and it’s more important to concentrate on tests themselves.

Any questions or comments? Ping me on LinkedIn or comment below. And if you liked this post, please give it a clap and share it with all of your friends.

Twitter: https://twitter.com/KyliaBoy
Linkedin: https://www.linkedin.com/in/andrew-kulta/

More articles you can find at:
https://blog.akyltech.com/