2
\$\begingroup\$

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.

asked Feb 10, 2015 at 1:55
\$\endgroup\$
1

1 Answer 1

2
\$\begingroup\$

Since you're on NUnit, why don't you just use its built-in TestCase attribute? Your test would then look like this:

[<TestCase("123", true)>]
[<TestCase("Foo", false)>]
[<TestCase("123Foo123", false)>]
let ``IsNumericTest``(candidate : string, expected : bool) =
 let actual = isNumeric candidate
 actual |> should equal expected

xUnit.net (a better unit testing framework for .NET) has a similar feature.

answered Feb 10, 2015 at 7:29
\$\endgroup\$
4
  • \$\begingroup\$ Because I didn't know about the TestCase attribute? ;) \$\endgroup\$ Commented Feb 10, 2015 at 14:08
  • \$\begingroup\$ Do you care to comment on my question on splitting out the Input value? \$\endgroup\$ Commented Feb 10, 2015 at 14:12
  • \$\begingroup\$ @SvenGrosen What specifically are you asking about? Is there a better way? Yes; I just showed you, but you must have something else in mind as well... \$\endgroup\$ Commented Feb 10, 2015 at 22:08
  • \$\begingroup\$ I can't think of a good way of asking it, which probably means I'm not prepared to truly ask it. Thank you for your help. \$\endgroup\$ Commented Feb 12, 2015 at 1:01

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.