Unit Testing with xUnit
Tags: csharp, testing, dotnet, beginners
Published: 2020-12-22 18:08:37

Before even writing a line of code, I always try to think of how I can unit test the classes and methods I'll write. Test-driven development at times may be tedious, but it is tremendously helpful in verifying your code works without running your program.

In Visual Studio, there are several testing frameworks that are offered out of the box, including MSTest, NUnit and xUnit. Of the three frameworks, my personal preference is xUnit. There are several reasons why I prefer this framework:

- Test isolation is built into the design
- It offers parallelization by default
- Reduction of attributes cluttering your code

# Test Isolation
When running tests, it's important that the context of each test be separate from each other. You wouldn't want to have the failure of one test to cause other tests to fail or to have the order in which tests are run play a role in a test's outcome. 

With the xUnit framework, tests are designed to be isolated much like the JUnit framework for Java. Each test is run on its own instance. Of course, if there is a need to have an object that's only created once, such as a database connection, fixtures can be used to share contexts in xUnit. But, as mentioned by [this post](https://martinfowler.com/bliki/JunitNewInstance.html) cited by the creators of xUnit, the idea is to make it difficult to design tests in a way that may be problematic.

# Parallelization
One of the newer features xUnit has to offer is that it offers parallelization of unit tests by default. If xUnit detects multiple collections (classes) of unit tests within the same assembly, it will parallelize them to make best use of your computing capacity. For example, one project I've worked on can run around 100 unit tests in just 2.5 seconds. 

While MSTest and NUnit do offer parallelization, it's not a default behavior like it is in xUnit. For MSTest and NUnit, attributes are required to specify that parallelization to take place. If you believe you do not require parallelization for your project, xUnit does allow you to [disable this feature](https://xunit.net/docs/running-tests-in-parallel#parallelism-in-test-frameworks) (see section `Changing Default Behavior`) through the use of attributes.

# Reduction of Attributes
One of the more subtle differences between xUnit and the MSTest and NUnit frameworks is the fewer number of attributes required to establish a test class. Under the xUnit framework, really the only attribute needed to setup a unit test is `[Fact]` above the test method, and you're good to go. You can setup your tests from a constructor, there's no need for the `[TestInitialize]` or `[SetUp]` attributes to initialize a test as you would need in MSTest or NUnit. In addition, there's no need for an attribute to declare your test class is indeed a test class, xUnit infers test classes by the unit tests within.

I enjoy the clean nature of xUnit. When I'm trying to write multiple test classes with multiple unit tests per class, having less code to write is a big win. I don't have to worry about trying to add in attributes to ensure my test runner can identify the test classes and its corresponding tests.

# Summary
While MSTest and NUnit are still great testing frameworks to work with, xUnit is my personal favorite among the bunch. It's incredibly performant, and the test isolation and clean nature of the framework gives me assurance that my unit tests are working as expected and easier to write and read.

# Related Reading
[NET Core 2: Why xUnit and not NUnit or MSTest](https://dev.to/hatsrumandcode/net-core-2-why-xunit-and-not-nunit-or-mstest--aei) by Chris Mathurin


## Credits
Banner - Peter Masełkowski - Unsplash.com