Splitting NUnit Unit Tests With TeamCity To Decrease CI Time

1354
Splitting NUnit Unit Tests With TeamCity To Decrease CI Time

This is a quick guide on how to split unit tests into different categories to decrease the time it takes for your CI build to run. The categories can be used to distinguish different areas of your tests to break down the CI Builds (typically used to run different categories in parallel) or to separate slow running tests into a separate build, all in the aim of speeding up the feedback cycle for developers. So to create a category you simple add a category attribute to either a test or a test fixture like so:

[Category("CategoryOne")] 
[TestFixture] 
public void FunkyMethod() 
{ 
    string pointless = "this is code"; 
} 

[Category("CategoryFour")] 
[TestFixture] 
public class UpgradeControllerTests 
{ 
    ... 

When segregating tests sometimes you will find a tests intersects multiple categories, in this case you can add multiple attributes. Later on we will see the different types of expressions you are able to enter when running the tests through TeamCity. Below is an example of using multiple categories

[Category("CategoryOne")] 
[Category("CategoryTwo")] 
[Test] 
public void FunkyMethod() 
{ 
    string pointless = "this is code"; 
}

So far creating categories like this is fine however having magic strings all over your code is not great. So to fix this we can create a custom attribute which does exactly the same thing as shown below. The custom attribute inherits from CategoryAttribute.

//Used for a test fixture 
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] 
public sealed class CategoryFiveAttribute : CategoryAttribute { } 
//Used for a test 
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] 
public sealed class CategoryThreeAttribute : CategoryAttribute { }

Now that we have the attributes ready we can use them like so.

[TestFixture, CategoryFiveAttribute] 
public class SignOutControllerTests 
{ 
...

To configure team city to run certain categories is fairly straightforward. Start by creating a Build step with the runner type set to “NUnit”.  Under Run tests from select your test project dll file. And then under Nunit categories include list the categories you want to test out by writing

/Include: CategoryOne

Note that you can also do the inverse and exclude certain tests by adding the following in the section named Nunit categories exclude

/Exclude: CategoryOne

NUnit also supports quite complex expressions, to see a full list click here (section “Specifying test categories to include or exclude”). 

A screenshot is included for a full list of settings.