FsUnit


What is FsUnit?

FsUnit is a set of libraries that makes unit-testing with F# more enjoyable. It adds a special syntax to your favorite .NET testing framework. FsUnit currently supports NUnit, xUnit, MbUnit, and MsTest (VS11 only).

The goals of FsUnit are:

  • to make unit-testing feel more at home in F# , i.e., more functional.
  • to leverage existing test frameworks while at the same time adapting them to the F# language in new ways.

NuGet packages are available for each of the supported testing frameworks:

Syntax

With FsUnit, you can write unit tests like this:

1: 
2: 
open NUnit.Framework
open FsUnit

One object equals or does not equal another:

1: 
2: 
1 |> should equal 1
1 |> should not' (equal 2)

One numeric object equals or does not equal another, with a specified tolerance:

1: 
2: 
10.1 |> should (equalWithin 0.1) 10.11
10.1 |> should not' ((equalWithin 0.001) 10.11)

A string does or does not start with or end with a specified substring:

1: 
2: 
3: 
4: 
5: 
6: 
"ships" |> should startWith "sh"
"ships" |> should not' (startWith "ss")
"ships" |> should endWith "ps"
"ships" |> should not' (endWith "ss")
"ships" |> should haveSubstring "hip"
"ships" |> should not' (haveSubstring "pip")

A List, Seq, or Array instance contains or does not contain a value:

1: 
2: 
[1] |> should contain 1
[] |> should not' (contain 1)

A List or Array instance has a certain length:

1: 
anArray |> should haveLength 4

A Collection instance has a certain count:

1: 
aCollection |> should haveCount 4

A function should throw a certain type of exception:

1: 
2: 
(fun () -> failwith "BOOM!" |> ignore) |> should throw typeof<System.Exception>
(fun () -> failwith "BOOM!" |> ignore) |> should (throwWithMessage "BOOM!") typeof<System.Exception>

A function should fail

1: 
shouldFail (fun () -> 5/0 |> ignore)

A number of assertions can be created using the be keyword:

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
34: 
35: 
36: 
37: 
38: 
39: 
40: 
41: 
42: 
43: 
true |> should be True
false |> should not' (be True)

"" |> should be EmptyString
"" |> should be NullOrEmptyString

null |> should be NullOrEmptyString
null |> should be Null
null |> should be null

anObj |> should not' (be Null)
anObj |> should not' (be null)
anObj |> should be (sameAs anObj)
anObj |> should not' (be sameAs otherObj)

11 |> should be (greaterThan 10)
9 |> should not' (be greaterThan 10)
11 |> should be (greaterThanOrEqualTo 10)
9 |> should not' (be greaterThanOrEqualTo 10)
10 |> should be (lessThan 11)
10 |> should not' (be lessThan 9)
10.0 |> should be (lessThanOrEqualTo 10.1)
10 |> should not' (be lessThanOrEqualTo 9)

0.0 |> should be ofExactType<float>
1 |> should not' (be ofExactType<obj>)

Choice<int, string>.Choice1Of2(42) |> should be (choice 1)

[] |> should be Empty
[1] |> should not' (be Empty)

"test" |> should be instanceOfType<string>
"test" |> should not' (be instanceOfType<int>)

2.0 |> should not' (be NaN)

[1;2;3] |> should be unique // Currently, NUnit only and requires version 1.0.1.0+

[1;2;3] |> should be ascending
[1;3;2] |> should not' (be ascending)
[3;2;1] |> should be descending
[3;1;2] |> should not' (be descending)

Visual Studio 11 Support

Visual Studio 11 support is available for all 4 of the targetted testing frameworks. FsUnit.MsTest is supported only in VS11 and no additional steps are required to use it. FsUnit for NUnit, FsUnit.MbUnit, and FsUnit.Xunit target F# 2.0 as well as F# 3.0. Because of this, a few additional steps are required in order to use these libraries in VS11. After installing one of these packages, add an App.config file to the project (if one doesn't already exist). Build the project and then run the command "Add-BindingRedirect projectname" (where projectname is the name of your test project) in the NuGet Package Manager Console. This command will update the App.config to include binding redirects from previous version of FSharp.Core to FSharp.Core version 4.3.0.0. More information about this command can be found in the NuGet documentation.

Test Projects Targeting Higher F# Runtimes

If you build your test project with a target F# runtime greater than the targeted runtime of the FsUnit assembly, you may find FsUnit operators failing at runtime, in which case you need to add a binding redirect to the App.config file.

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-999.999.999.999" newVersion="4.4.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

Contributing

The project is hosted on GitHub where you can report issues, fork the project and submit pull requests. If you're adding a new public API, please also consider adding samples that can be turned into a documentation. You might also want to read the library design notes to understand how it works.

Fork me on GitHub