A Swiss Army Katana

Before now, test methods for the Fixie test framework had to have zero parameters. If your test method had a parameter, it would fail without being called. Fixie would have no idea what values to pass in. As of Fixie, you can define your own conventions for parameterized tests. As a convention author, you decide what it means for a test to have parameters. For example, let’s say you want your parameter values to come from attributes on the method, similar to xUnit theories:

Our intention is for these 2 test methods to be treated as 5 test cases, producing 5 individual pass/fail results. Out of the box, Fixie has no idea what [Input] means. In order to let Fixie know about our intentions, we can define the attribute and a custom convention:

Your own convention wouldn’t have to be attribute-based. All that Fixie cares about is that you provide it some Func<MethodInfo, IEnumerable<object[]>>. That’s a mouthful, so let’s break it down:

  1. Parameters(…) accepts a function that explains what inputs to use for any given test method.
  2. Your function is given the MethodInfo that describes a single test method.
  3. Your function yields any number of object arrays.
  4. Each object array that you yield represents a single call to the test method. If the method takes in 3 parameters, your arrays better have 3 values with corresponding types.

Func<MethodInfo, IEnumerable<object[]>> is a Swiss Army Katana. It’s versatile, but sharp. It will enable us to do a wide variety of things, but it’s easy to misuse. It represents exactly what the .NET reflection API needs in order to call the method, so no matter what sugar I layer on top of it, Func<MethodInfo, IEnumerable<object[]>> is the truth under the hood. After developing a few more examples, it’ll be more clear how a few convenient overloads of the Parameters() method could make it easier to get things right in the most common situations.

In my next post, we’ll take a little detour to see why such a small change was so hard to implement.

Test Execution Order