NUnit TestFixture C# Tutorial

NUnit TestFixture attribute is a class level attribute and it indicates that this class contains NUnit Test Methods.

Below are the topics we covered in this tutorial:

  1. TestFixture Example and Usage
  2. Parameterized TestFixtures
  3. TestFixture Inheritance
  4. Generic TestFixture
  5. TestFixture Restrictions

NUnit TestFixture Example and Usage

Below is the example usage of TestFixture NUnit attribute.

using NUnit.Framework;

namespace CustomerOrderService.Tests
{
    [TestFixture]
    public class CustomerOrderServiceTests
    {
    }
}

Remember: TestFixture can only be placed on class not on methods. You can learn more about writing test case methods here.

Parameterized / Arguments TestFixtures

Sometimes our NUnit class needs arguments. We can pass arguments to TestFixture class through constructors. We can pass arguments in TestFixture attribute like shown below:

[TestFixture(CustomerType.Basic)]
public class CustomerOrderServiceTests
{
    private CustomerType customerType;

    public CustomerOrderServiceTests(CustomerType customerType)
    {
        this.customerType = customerType;
    }
}

In the above example, our class needs CustomerType as parameter so we create a constructor and specify the CustomerType as parameter. We provide value to parameters in TestFixture as CustomerType.Basic.

If the NUnit framework did not found any matching TestFixture attribute for example, if we did not pass CustomerType.Basic as argument then NUnit framework give below error.

Message: OneTimeSetup: No suitable constructor was found

We can create multiple constructors and pass multiple parameters through TestFixture. Below is the example:

[TestFixture(CustomerType.Premium, 100.00)]
[TestFixture(CustomerType.Basic)]
public class CustomerOrderServiceTests
{
    private CustomerType customerType;
    private double minOrder;

    public CustomerOrderServiceTests(CustomerType customerType, double minOrder)
    {
        this.customerType = customerType;
        this.minOrder = minOrder;
    }

    public CustomerOrderServiceTests(CustomerType customerType) : this(customerType, 0)
    {
    }

    [TestCase]
    public void TestMethod()
    {
        Assert.IsTrue((customerType == CustomerType.Basic && minOrder == 0 || customerType == CustomerType.Premium && minOrder > 0));
    }
}

When we create multiple constructors NUnit will create separate objects using each constructor. For example in the above example, NUnit will create two separate test methods using each constructor parameters.

NUnit TestFixture

NUnit TestFixture Inheritance

A TestFixture attribute supports inheritance that means we can apply TestFixture attribute on base class and inherit from derived Test Classes. A base class can be an Abstract class.

Abstract Fixture Pattern

This pattern is used when we have to validating the logic of base class and make sure that derived class does not violate the base class implementation.

For example, we have a base Employee class and two inherit Manager and DeliveryManager classes. We have some validations in Employee class and we write some test cases for Employee class and we need to make sure these validations must verify by the derived classes.

public abstract class Employee
{
    public string Name { get; set; }

    public bool ContainsIllegalChars()
    {
        if (this.Name.Contains("$"))
        {
            return true;
        }
        return false;
    }
}

public class Manager : Employee {}

public class DeliveryManager : Employee {}

Test Cases

using NUnit.Framework;

namespace EmployeeService.Tests
{
    [TestFixture]
    public class EmployeeTests
    {
        public virtual Employee CreateEmployee()
        {
            return new Employee();
        }

        [TestCase]
        public void When_NameContainsIllegalChars_Expect_ContainsIllegalChars_ReturnsTrue()
        {
            Employee employee = CreateEmployee();
            employee.Name = "Da$ya";

            var result = employee.ContainsIllegalChars();

            Assert.IsTrue(result);
        }
    }

    public class ManagerTests : EmployeeTests
    {
        public override Employee CreateEmployee()
        {
            return new Manager();
        }
    }

    public class VicePresidentTests : EmployeeTests
    {
        public override Employee CreateEmployee()
        {
            return new DeliveryManager();
        }
    }
}

We have created a EmployeeTests class in C#. Created a virtual method CreateEmployee which will create a new instance of Employee class and can override by derived classes. Write a test method which test the ContainsIllegalChars method of Emplyee class.

Create two other Tests Classes ManagerTests and VicePresidentTests which inherits from EmployeeTests classes. Note we have not used TestFixture attribute on derived classes. It is automatically derived by inherited classes.

We override the CreateEmployee method and return derived classes of Employee class.  NUnit framework will create three different test methods for all three classes. Below is the screenshot:

TestFixture Inheritance

Generic TestFixture

In addition to parameters, we can also give indication to NUnit which data types are passing into the TestFixture attribute. Below is the example.

[TestFixture(CustomerType.Premium, 100.00, TypeArgs = new Type[] { typeof(CustomerType), typeof(double) })]
public class CustomerOrderServiceTests<T1, T2>
{
    private T1 customerType;
    private T2 minOrder;

    public CustomerOrderServiceTests(T1 customerType, T2 minOrder)
    {
        this.customerType = customerType;
        this.minOrder = minOrder;
    }

    [TestCase]
    public void TestMethod()
    {
        Assert.That(customerType, Is.TypeOf<CustomerType>());
        Assert.That(minOrder, Is.TypeOf<double>());
    }
}

In the above example, we specify the parameters and then using TypeArgs specify the typeof arguments. In the TestMethod, we are passing correct Type as generic arguments or not. 

TestFixture Restrictions

Below are some restrictions/points about TestFixture attribute.

  • It can only place on class.
  • If no arguments is provided in TestFixture attribute then class must have default constructor.
  • If arguments is provided in TestFixture attribute then class must have matching constructor.
  • We can place multiple TestFixture attributes on a single class.
  • TestFixture attribute can be inherited
  • We can provide generic arguments to TestFixture class.
  • We can apply TestFixture attribute on abstract class.Â