I'm just getting started with F# and was writing some unit tests for some functionality I had written. In the interest of brevity, I decided to create some lists of the different test cases and just run through them all in one test instead of creating separate test methods for each one (I'm not focusing on that design decision here, just pointing it out as otherwise my question won't make much sense).
So here's my code:
// simple helper to cut down on repeated code
let testRunner cases func =
cases |> List.map func
// isNumeric is the function under test, its functionality should be obvious
[<Test>]
let ``IsNumericTest``() =
let testCases = ["123"; "Foo"; "123Foo123"]
let expectedResults = [true; false; false]
let results = testRunner testCases isNumeric
results |> should equal expectedResults
I started thinking about creating a simple type to encapsulate the test case input and the expected result, something like this:
type TestCase = { Input : string; ExpectedResult : bool}
type TestCases = TestCase list
let testCases = [{Input="123"; ExpectedResult=true};{Input="Foo"; ExpectedResult=false}; {Input="123Foo123"; ExpectedResult=false}]
Then I struggled to think of how to split each of those down to use in my testRunner
method until I came up with this:
let results = testRunner (testCases |> List.map (fun (T) -> T.Input)) isNumeric
results |> should equal (testCases |> List.map (fun (T) -> T.ExpectedResult))
But that just looks ugly. Is there a better way to split out the Input
value for my testRunner
method? I am fine with changing it, but figured that while my question is specific to a unit testing scenario, the lessons I should learn would be widely applicable.