Phillip Trelford's Array

POKE 36879,255

5 lesser known F# testing tools & techniques

Most common .Net testing tools work in F#, but that’s not the end of the story. F# adds many more tools and techniques besides, lets take a look at a few of them:

1) Back tick methods

F# lets you write method names with whitespace by escaping the name in back-ticks:

let [<Fact>] ``2 + 2 should equal 4`` () =
    Assert.Equal(4, 2+2)

This is also handy when writing step definitions for acceptance tests:

let [<Then>] ``I should have (.*) black jumpers in stock`` (n:int) =     
    let passed = (stockItem.Count = n)

TickSpec provides a lightweight library for automating acceptance tests in F# along with SpecFlow which now supports back-tick methods (although for SpecFlow you’ll need a C# project too).

2) Mocking

In F# you can easily create mock objects without frameworks using object expressions:

let [<Test>] ``at 15:00 the sun image should be expected`` () =
    let time = { new ITime with member __.GetHour () = 15 }
    // ...

Along with all the standard .Net mocking frameworks like Moq, F# also has Foq:

let [<Test>] ``at 01:00 the moon image should be expected`` () =
    let time = Mock<ITime>.With(fun mock -> <@ mock.GetHour() --> 01 @>)
    // ...

And now there’s AutoFixture support in the form of AutoFixture.AutoFoq.

3) Fluent Assertions

FsUnit lets you write your assertions very close to how you might write your test names:

let [<Test>] ``2 + 2 should equal 4`` () =
    2 + 2 |> should equal 4

While unquote lets you write tests like code:

let [<Test>] ``2 + 2 = 4`` () = 
    test <@ 2 + 2 = 4 @>

4) FsCheck

FsCheck is a random testing framework based on Haskell’s QuickCheck that lets you assert properties on functions:

let revRevIsOrig (xs:list<int>) = List.rev(List.rev xs) = xs
Check.Quick revRevIsOrig

In the check above FsCheck will randomly create lists of integers to test that the property holds (reversing a list twice should take you back to the original list). If it fails it pares back the input to the shortest list that would make the property fail.

5) Code Coverage

Not F# specific per se, but full fat Visual Studio 2012 comes with a test runner and code coverage tools built-in, it even highlights code that isn’t covered by tests for you:

Code Coverage Facts

Happy testing!

Comments (2) -

  • Vasily Kirichenko

    10/6/2013 10:56:31 PM |

    Your Unquote sample may be better written like this:

    let [<Test>] ``2 + 2 = 4`` () =
        2 + 2 =? 4

  • Christian Abildsø

    10/17/2013 3:34:28 AM |

    Something to keep in mind when using backtick naming is that packages relying on reflection may trip up on any periods you have in the name, thinking it's dot notation instead. I know that's the case with Testdriven.NET for example. So I've started leaving periods out of my test names.

Comments are closed