Craftsmanship in software strives for high, predictable, repeatable and affordable quality. This is the reason why we care about design, code reviews and of course testing. Test Driven Development helps us create a flexible implementation that meets the expectations of our clients in terms of features, performance and quality. As professionals we have to master as many tools as possible to reach our goal of steadily providing value.
Property based testing
The above is the reason why I am exploring Property Based Testing. I like to think about it as "Let the machine do the heavy lifting for you" or as John Huges says "Don't write tests, generate them".
I am not claiming that you should stop writing unit tests. I find that when driving the design Outside-in hence declaring the relations between my components, unit tests are the tool to use. Sometimes when I want to discover deeper properties of my domain, I am faced with features that have more edge cases than my brain could handle. In such cases, generating a wide array of inputs to test my program is appealing. This is where I think property testing becomes a viable tool.
If you are asking "How can I set up a development environment in .NET that would allow me to experiment and work with this tool?" the following tutorial is for you.
Development environment details
Windows 10 Home Edition
Visual Studio 2013 version 12 Update 5
Resharper version 8.2.3
NCrunch version 18.104.22.168
FsCheck version 2.2.2
FsCheck.NUnit version 2.2.2
NUnit version 2.6.4
Open Visual Studio and create an F# Project
Open the Nuget Package Manager following TOOLS > Nuget Package Manager > Package Manager Console from the main menu and type
Comment out the content in FsCheckAddin.fs file to allow NCrunch to run the tests
//[<NUnitAddin(Description = "FsCheck addin")>] //type FsCheckAddin() = // interface IAddin with // override x.Install host = // let tcBuilder = new FsCheckTestCaseBuilder() // host.GetExtensionPoint("TestCaseBuilders").Install(tcBuilder) // true
The output shows the "shrinking process" from the sixth input (identified by 5:) original value [-3; 1; 5; -3; 6; 2; 6; -2] to the "shrunk" (reduced) input [1; 0] that still falsifies (makes it fail) the property
Let's correct the property as the reverse of the reverse of a list is equal to the original
type ListProperties =
static member ReverseOfReverseIsAsTheOriginal (xs:int list) =
List.rev (List.rev xs) = xs
Re-run the tests that should be all green by now and read the output. You'll notice it's very verbose as expected and shows all the inputs used to verify the property.
You are now ready to experiment with FsCheck! Let me know what is your experience with property based testing in F#.