Practical ASP.NET

What's Fixie and Why Should C# Programmers Care?

It's what unit testing should be. Here's how to use it to test your apps.

Fixie is a relative newcomer to the .NET testing framework space. Just as with other testing frameworks such as NUnit or xUnit.net, Fixie allows test methods to be created and executed. The difference with Fixie is that it takes a conventions-based approach, which is a benefit as we do not need to use attributes to mark classes and methods as tests.

Using other testing frameworks usually involves having to decorate classes and/or methods with attributes that tell the test runner (e.g. Visual Studio Test Explorer) that this is a test that can be executed.

With Fixie, this "test discovery" is not enabled through attributes, but rather by following a set of default conventions.

Once installed (via NuGet) out of the box, Fixie comes with a set of default conventions that describe test discovery. The first convention has to do with how test classes are named. To create a test class it is simply named as you wish but postfixed with "Tests". This then tells Fixie that the class contains test methods.

Once a test class has been created, individual tests can be added as methods. The default convention for test methods is to name them however you wish, but make them public and return void (or make the method an async method).

The following codes shows a complete test class C# file:

namespace Calculator.Tests
{
    public class SimpleCalculatorTests
    {
        public void ShouldAddTwoNumbers()
        {
            var sut = new SimpleCalculator();

            var result = sut.Add(1, 2);
        }

        public void ShouldAddThreeNumbers()
        {
            var sut = new SimpleCalculator();

            var result = sut.Add(1, 2, 3);
        }
    }
}

If the test project is built, Visual Studio Test Explorer will now show these two tests as Figure 1 shows.

Visual Studio Test Explorer showing Fixie Tests
[Click on image for larger view.] Figure 1: Visual Studio Test Explorer showing Fixie Tests

Notice that we have not had to add any attributes to either the test class (such as NUnit's [TestFixture] attribute, or the test methods (such as xUnit.net [Fact] attribute).

If we change one of the tests so that it does not match the default convention, for example making the test non-void as follows:

public int ShouldAddTwoNumbers()
{
    var sut = new SimpleCalculator();

    var result = sut.Add(1, 2);

    return result;
}

Building the solution now results in this test disappearing from Test Explorer as Figure 2 shows.

Only One Test Now Matches the Default Convention
[Click on image for larger view.] Figure 2: Only One Test Now Matches the Default Convention

Custom Conventions
If these default conventions do not suit us, it is possible to define our own conventions.

For example, suppose that all classes that end with the word "Fixture" are to be test classes, and any non-void methods are to be recognised as test methods. To accomplish this a custom convention class can be defined.

To do this, a new class is created in the test project that inherits from Fixies's Convention class:

using Fixie;

namespace Calculator.Tests
{
    class MyCustomConvention : Convention
    {
        public MyCustomConvention()
        {
            Classes.NameEndsWith("Fixture");

            Methods.Where(method => !method.IsVoid());
        }
    }
}

Notice that the constructor of the custom convention class is used to define the conventions that we want to use. The first part is to define what constitutes a test class; to do this the Classes property of the inherited Convention class is used. In the preceding code sample it is used to state that all test classes must end with "Fixture". The second part is to define what methods will be recognized as tests. To do this the Methods property of the inherited Convention class is used; in the preceding code, non-void methods will be recognized.

Now that the custom convention has been defined, the test code can be changed:

namespace Calculator.Tests
{
    public class SimpleCalculatorFixture
    {
        public int ShouldAddTwoNumbers()
        {
            var sut = new SimpleCalculator();

            var result = sut.Add(1, 2);

            return result;
        }

        public int ShouldAddThreeNumbers()
        {
            var sut = new SimpleCalculator();

            var result = sut.Add(1, 2, 3);

            return result;
        }
    }
}

In this modified test code the class now ends with "Fixture" and both test methods return int rather than void.

If the project is built again, the tests now show up because they match the custom convention as Figure 3 shows.

Custom Convention in Action
[Click on image for larger view.] Figure 3: Custom Convention in Action

One final thing to note about Fixie is that is does not come bundled with an assertion library. Instead, a separate NuGet package can be installed to write test asserts, such as Should, Shouldly, or even NUnit or xUnit.net asserts.

About the Author

Jason Roberts is a Microsoft C# MVP with over 15 years experience. He writes a blog at http://dontcodetired.com, has produced numerous Pluralsight courses, and can be found on Twitter as @robertsjason.

comments powered by Disqus

Featured

Subscribe on YouTube