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 0.0.1.98, 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:
- Parameters(…) accepts a function that explains what inputs to use for any given test method.
- Your function is given the MethodInfo that describes a single test method.
- Your function yields any number of object arrays.
- 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.