xUnit is an extremely extensible unit testing framework!
If you need to control the order of your unit tests, then all you have to do is implement an ITestCaseOrderer. Once implemented, you just add a TestCaseOrdererAttribute to the top of your test class to use it. Below we use a custom OrderAttribute to order the tests.
To control the order of the test collections you can do a very similar trick by implementing an ITestCollectionOrderer. However, an ITestCollection is not neccessarily associated with a specific class, so to to use attributes to order them you need to use a little reflection. Check out the sample below for details.
Implementation
/// <summary>
/// Used by CustomOrderer
/// </summary>
public class OrderAttribute : Attribute
{
public int I { get; }
public OrderAttribute(int i)
{
I = i;
}
}
/// <summary>
/// Custom xUnit test collection orderer that uses the OrderAttribute
/// </summary>
public class CustomTestCollectionOrderer : ITestCollectionOrderer
{
public const string TypeName = "xUnitCustom.CustomTestCollectionOrderer";
public const string AssembyName = "xUnitCustom";
public IEnumerable<ITestCollection> OrderTestCollections(
IEnumerable<ITestCollection> testCollections)
{
return testCollections.OrderBy(GetOrder);
}
/// <summary>
/// Test collections are not bound to a specific class, however they
/// are named by default with the type name as a suffix. We try to
/// get the class name from the DisplayName and then use reflection to
/// find the class and OrderAttribute.
/// </summary>
private static int GetOrder(
ITestCollection testCollection)
{
var i = testCollection.DisplayName.LastIndexOf(' ');
if (i <= -1)
return 0;
var className = testCollection.DisplayName.Substring(i + 1);
var type = Type.GetType(className);
if (type == null)
return 0;
var attr = type.GetCustomAttribute<OrderAttribute>();
return attr?.I ?? 0;
}
}