16 December 2010

F#, xUnit theories and InlineData

How do you know you haven’t blogged much lately? When you want to write a blog post and you forgot the name of the thing you’re actually writing it with. “Wait, it’s called Window Live something something…what did that icon look like again?”. Also, Windows Live Writer now has a ribbon! Good stuff.

Anyway, just a short heads up to save people some time: in the xUnit extensions, there is a Theory attribute which in combination with the InlineData attribute lets you specify a parameterized xUnit test. The InlineData attribute lets you specify the values the test should run with (you can’t test everything randomly with FsCheck, you know). That and other xUnit extension goodies are explained here.

My point is – this attribute does not work in F# (or managed C++), because the AttributeUsage attribute on the InlineData attribute is defined on its parent class, DataAttribute. It is correctly defined as Inherited = true; but only the C# compiler seems to honour this. More detailed explanation in this stackoverflow post. If  you care about this, please vote for the bug on the xUnit site!

Luckily, the workaround is not too bad – just use the PropertyData attribute instead:

let symbolTestData = 
    [ "an1 rest",           "an1"
      "?test bla",          "?test"
      "?+_est bla",         "?+_est"
      "+_123 bla",          "?+_123"
      "+._1.2.3 bla",       "+._1.2.3"
      "+_q1r-2g3! bla",     "+_q1r-2g3!"
      "abc.def.feg/q bla",  "abc.def.feg/q"
      "ab/cd? bla",         "ab/cd?"
    ]
    |> Seq.map (fun (a,b) -> [|a; b|])

[<Theory>]
[<PropertyData("symbolTestData")>]
let ``should parse symbol``(toParse:string, result:string) =
    Assert.Equal(result, run symbol result)

Note that xUnit actually expects a sequence of arrays, but I think the list of tuples looks better, at the small cost of an extra conversion step.

Technorati Tags: ,,
Share this post :