Sunday, April 24, 2016

How to Order xUnit Tests and Collections

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;
    }
}

Sunday, April 10, 2016

RangeSet for .NET

Update 4/13 - Added support for single value ranges.

What data structure do you use when you need to efficiently check if a number is within a large set of ranges?

If you require that the ranges do not overlap, then it is simple to keep a balanced binary tree of the ranges. Finding if a number is within one of those ranges should only take O(log n) to find. Below is an implementation of a RangedSet that uses a standard .NET SortedSet to store the ranges.

IRangeSet Interface

public interface IRangeSet<in T> where T : IComparable
{
    void AddRange(T min, T max);
 
    bool Contains(T findValue);
}

Friday, April 1, 2016

Real Time Web Analytics