I just got started with F#, which is my first functional language. I have been working quasi-exclusively with C#, and enjoy a lot how F# leads me to re-think how I write code. One aspect I find a bit disorienting is the change in the process of writing code. I have been using TDD for years in C# now, and really appreciate to have unit tests to know where I am at. So far, my process with F# has been to write some functions, play with them with the interactive console until I am "reasonably" sure they work, and tweak & combine. This works well on small-scale problems like the Euler Project, but I can't imagine building something large that way.
How do people approach unit testing and building a test suite for a F# program? Is there an equivalent to TDD? Any pointers or thoughts are appreciated.
views:
1064answers:
6You could have a look at FSUnit - though I haven't used it yet, it might worth a try. Certainly better than using for example (native) NUnit in F#.
I think this is a very interesting question that I have wondered about a lot myself. My thoughts so far are only thoughts, so take them for what they are.
I think that the safety net of an automated test suite is too valuable an asset to let go, however luring that interactive console may be, so I paln to continue writing unit tests as I've always had.
One of the main strengths of .NET is the cross-language capabilities. I know I'm going to be writing F# production code soon, but my plan is to write unit tests in C# to ease my way into what is for me a new language. In this way, I also get to test that what I write in F# will be compabible with C# (and other .NET languages).
With this approach, I understand that there are certain features of F# that I can only use internally in my F# code, but not expose as part of my public API, but I will accept that, just as I accept today that there are certaing things C# allows me to express (like uint) that aren't CLS compliant, and so I refrain from using them.
Test-driven developers should feel right at home in functional languages like F#: small functions that give deterministically repeatable results lend themselves perfectly to unit tests. There are also capabilities in the F# language that facilitate writing tests. Take, for example, Object Expressions. You can very easily write fakes for functions that take as their input an interface type.
If anything, F# is a first-class object-oriented language and you can use the same tools and tricks that you use when doing TDD in C#. There are also some testing tools written in or specifically for F#:
Matthew Podwysocki wrote a great series on unit testing in functional languages. Uncle Bob also wrote a thought provoking article here.
Have a look at FsCheck, an automatic testing tool for F#, is basically a port of Haskell's QuickCheck. It allows you to provide a specification of the program, in the form of properties that the functions or methods should satisfy, and FsCheck tests that the properties hold in a large number of randomly generated cases.
I use NUnit, and it doesn't strike me as hard to read or onerous to write:
open NUnit.Framework
[<TestFixture>]
type myFixture() = class
[<Test>]
member self.myTest() =
//test code
end
Since my code is a mix of F# and other .Net languages, I like the fact that I write the unit tests in basically the same fashion and with similar syntax in both F# and C#.
As dglaubman suggests you can use NUnit. xUnit.net also provides support for this and works well with TestDriven.net. The code looks similar to NUnit tests but without the requirement to wrap the test in a containing type.
#light
// Supply a module name here not a combination of module and namespace, otherwise
// F# cannot resolve individual tests nfrom the UI.
module NBody.DomainModel.FSharp.Tests
open System
open Xunit
open Internal
[<Fact>]
let CreateOctantBoundaryReordersMinMax() =
let Max = VectorFloat(1.0, 1.0, 1.0)
let Min = VectorFloat(-1.0, -1.0, -1.0)
let result = OctantBoundary.create Min Max
Assert.Equal(Min, result.Min)
Assert.Equal(Max, result.Max)