FsUnit


FsUnit for NUnit

The FsUnit library for NUnit can be installed from NuGet:
PM> Install-Package FsUnit
Sample FsUnit tests for NUnit can be installed from NuGet:
PM> Install-Package FsUnit.Sample

Initialization

If you reference FsUnit from NuGet and want to use pretty-printed F# value types in error messages, you have to register custom values formatters.

SetUpFixture

Add following piece of code to your assembly to register formatter for namespace or entire assembly

open FsUnit
open NUnit.Framework

[<SetUpFixture>]
type InitMsgUtils() =
    inherit FSharpCustomMessageFormatter()

The OneTimeSetUp method in a SetUpFixture is executed once before any of the fixtures contained in its namespace. A SetUpFixture outside of any namespace provides SetUp and TearDown for the entire assembly.

In F# you can use namespace global to create InitMsgUtils outside of any namespace.

SetUp

As an alternative solution you can initialize FSharpCustomMessageFormatter for single test fixture from your setup method:

open FsUnit

[<TestFixture>]
type MyTests () =

    [<SetUp>]
    member __.setup () =
        FSharpCustomMessageFormatter() |> ignore

Euler - Problem 1

module ``Project Euler - Problem 1`` =
    open NUnit.Framework
    open FsUnit

    let GetSumOfMultiplesOf3And5 max =
        seq{3..max-1} |> Seq.fold(fun acc number ->
                            (if (number % 3 = 0 || number % 5 = 0) then
                                acc + number else acc)) 0

    [<Test>]
    let ``When getting sum of multiples of 3 and 5 to a max number of 10 it should return a sum of 23`` () =
        GetSumOfMultiplesOf3And5(10) |> should equal 23

LightBulb

module ``LightBulb Tests`` =
    open NUnit.Framework
    open FsUnit

    type LightBulb(state) =
        member x.On = state
        override x.ToString() =
            match x.On with
            | true  -> "On"
            | false -> "Off"

    [<TestFixture>]
    type ``Given a LightBulb that has had its state set to true`` ()=
        let lightBulb = new LightBulb(true)

        [<Test>] member x.
         ``when I ask whether it is On it answers true.`` ()=
                lightBulb.On |> should be True

        [<Test>] member x.
         ``when I convert it to a string it becomes "On".`` ()=
                string lightBulb |> should equal "On"

    [<TestFixture>]
    type ``Given a LightBulb that has had its state set to false`` ()=
        let lightBulb = new LightBulb(false)

        [<Test>] member x.
         ``when I ask whether it is On it answers false.`` ()=
                lightBulb.On |> should be False

        [<Test>] member x.
         ``when I convert it to a string it becomes "Off".`` ()=
                string lightBulb |> should equal "Off"

BowlingGame

Thanks to Keith Nicholas and Julian from hubFS for this example!

module ``BowlingGame A game of bowling`` =
    open NUnit.Framework
    open FsUnit

    let (|EndOfGame|IncompleteStrike|Strike|Normal|Other|) (l, frame) =
        match l with
        | _ when frame = 11            -> EndOfGame(0)
        | [10;s]                       -> IncompleteStrike(10+s+s)
        | 10::s::n::tail               -> Strike(10+s+n, s::n::tail)
        |  f::s::n::tail when f+s = 10 -> Normal(f+s+n,  n::tail)
        |  f::s::n::tail               -> Normal(f+s,    n::tail)
        | ls                           -> Other(List.fold (+) 0 ls)

    let scoreBowls bowls =
        let rec scoreBowls' frame l current_score =
            let nextframe = scoreBowls' (frame+1)
            match (l, frame) with
            | EndOfGame(score)        -> current_score + score
            | IncompleteStrike(score) -> current_score + score
            | Strike(score, l)        -> nextframe l (current_score + score)
            | Normal(score, l)        -> nextframe l (current_score + score)
            | Other(score)            -> current_score + score
        scoreBowls' 1 bowls 0

    [<Test>]
    let ``with simple scores should get the expected score.`` () =
        scoreBowls [1;2;3] |> should equal 6

    [<Test>]
    let ``with a spare should get the expected score (spare).`` () =
        scoreBowls [2;8;1] |> should equal 12

    [<Test>]
    let ``with a strike should get the expected score (strike).`` () =
        scoreBowls [10;1;2] |> should equal 16

    [<Test>]
    let ``that is perfect should get a score of 300.``() =
        scoreBowls [for i in 1..18 -> 10] |> should equal 300

    [<Test>]
    let ``with spares in the last frame should get the expected score (spare in last frame).`` () =
        scoreBowls ([for i in 1..18 -> 0] @ [2;8;1]) |> should equal 11

    [<Test>]
    let ``with a strike in the last frame should get the expected score (strike in last frame).`` () =
        scoreBowls ([for i in 1..18 -> 0] @ [10;10;1]) |> should equal 21

    [<Test>]
    let ``with double strikes should add the score of the first strike to the score of the second.`` () =
        scoreBowls [10;10;1] |> should equal 33

    [<Test>]
    let ``that looks like an average bowler's game should get the expected score (example game).`` () =
        scoreBowls [1;4;4;5;6;4;5;5;10;0;1;7;3;6;4;10;2;8;6] |> should equal 133

Note: NUnit can also be utilized without specifying a type as in the examples for xUnit

Multiple items
Namespace NUnit

--------------------
type NUnitAttribute = inherit Attribute new: unit -> unit
<summary> Abstract base class for all custom attributes defined by NUnit. </summary>

--------------------
NUnitAttribute() : NUnitAttribute
Namespace NUnit.Framework
Namespace FsUnit
Multiple items
type SetUpFixtureAttribute = inherit NUnitAttribute interface IFixtureBuilder new: unit -> unit member BuildFrom: typeInfo: ITypeInfo -> IEnumerable<TestSuite>
<summary> Identifies a class as containing <see cref="T:NUnit.Framework.OneTimeSetUpAttribute" /> or <see cref="T:NUnit.Framework.OneTimeTearDownAttribute" /> methods for all the test fixtures under a given namespace. </summary>

--------------------
SetUpFixtureAttribute() : SetUpFixtureAttribute
Multiple items
type InitMsgUtils = inherit FSharpCustomMessageFormatter new: unit -> InitMsgUtils

--------------------
new: unit -> InitMsgUtils
Multiple items
type FSharpCustomMessageFormatter = new: unit -> FSharpCustomMessageFormatter

--------------------
new: unit -> FSharpCustomMessageFormatter
Multiple items
type TestFixtureAttribute = inherit NUnitAttribute interface IFixtureBuilder2 interface IFixtureBuilder interface ITestFixtureData interface ITestData new: unit -> unit + 1 Überladung member BuildFrom: typeInfo: ITypeInfo -> IEnumerable<TestSuite> + 1 Überladung member Arguments: obj array member Author: string member Category: string ...
<summary> Marks the class as a TestFixture. </summary>

--------------------
TestFixtureAttribute() : TestFixtureAttribute
TestFixtureAttribute([<System.ParamArray>] arguments: obj array) : TestFixtureAttribute
Multiple items
type MyTests = new: unit -> MyTests member setup: unit -> unit

--------------------
new: unit -> MyTests
Multiple items
type SetUpAttribute = inherit NUnitAttribute new: unit -> unit
<summary> Identifies a method to be called immediately before each test is run. </summary>

--------------------
SetUpAttribute() : SetUpAttribute
val ignore: value: 'T -> unit
val GetSumOfMultiplesOf3And5: max: int -> int
val max: int
Multiple items
val seq: sequence: 'T seq -> 'T seq

--------------------
type 'T seq = System.Collections.Generic.IEnumerable<'T>
Modul Seq aus Microsoft.FSharp.Collections
val fold<'T,'State> : folder: ('State -> 'T -> 'State) -> state: 'State -> source: 'T seq -> 'State
val acc: int
val number: int
Multiple items
type TestAttribute = inherit NUnitAttribute interface ISimpleTestBuilder interface IApplyToTest interface IImplyFixture new: unit -> unit member ApplyToTest: test: Test -> unit member BuildFrom: method: IMethodInfo * suite: Test -> TestMethod member Author: string member Description: string member ExpectedResult: obj ...
<summary> Marks the method as callable from the NUnit test runner. </summary>
<example> [TestFixture] public class Fixture { [Test] public void MethodToTest() {} [Test(Description = "more detailed description")] public void TestDescriptionMethod() {} } </example>


--------------------
TestAttribute() : TestAttribute
val should: f: ('a -> #Constraints.Constraint) -> x: 'a -> actual: obj -> unit
val equal: expected: 'a -> Constraints.EqualConstraint (requires equality)
Multiple items
type LightBulb = new: state: bool -> LightBulb override ToString: unit -> string member On: bool

--------------------
new: state: bool -> LightBulb
val state: bool
val x: LightBulb
Eigenschaft LightBulb.On: bool with get
val lightBulb: LightBulb
val x: Given a LightBulb that has had its state set to true
val be: ('a -> 'a)
val True: Constraints.TrueConstraint
Multiple items
val string: value: 'T -> string

--------------------
type string = System.String
val x: Given a LightBulb that has had its state set to false
val False: Constraints.FalseConstraint
val l: int list
val frame: int
aktives Musterergebnis EndOfGame: int list * int -> Choice<int,int,(int * int list),(int * int list),int>
val s: int
aktives Musterergebnis IncompleteStrike: int list * int -> Choice<int,int,(int * int list),(int * int list),int>
val n: int
val tail: int list
aktives Musterergebnis Strike: int list * int -> Choice<int,int,(int * int list),(int * int list),int>
val f: int
aktives Musterergebnis Normal: int list * int -> Choice<int,int,(int * int list),(int * int list),int>
val ls: int list
aktives Musterergebnis Other: int list * int -> Choice<int,int,(int * int list),(int * int list),int>
Multiple items
Modul List aus Microsoft.FSharp.Collections

--------------------
type List<'T> = | op_Nil | op_ColonColon of Head: 'T * Tail: 'T list interface IReadOnlyList<'T> interface IReadOnlyCollection<'T> interface IEnumerable interface IEnumerable<'T> member GetReverseIndex: rank: int * offset: int -> int member GetSlice: startIndex: int option * endIndex: int option -> 'T list static member Cons: head: 'T * tail: 'T list -> 'T list member Head: 'T member IsEmpty: bool member Item: index: int -> 'T with get ...
val fold<'T,'State> : folder: ('State -> 'T -> 'State) -> state: 'State -> list: 'T list -> 'State
val scoreBowls: bowls: int list -> int
val bowls: int list
val scoreBowls': frame: int -> l: int list -> current_score: int -> int
val current_score: int
val nextframe: (int list -> int -> int)
aktive Erkennung EndOfGame: int list * int -> Choice<int,int,(int * int list),(int * int list),int>
val score: int
aktive Erkennung IncompleteStrike: int list * int -> Choice<int,int,(int * int list),(int * int list),int>
aktive Erkennung Strike: int list * int -> Choice<int,int,(int * int list),(int * int list),int>
aktive Erkennung Normal: int list * int -> Choice<int,int,(int * int list),(int * int list),int>
aktive Erkennung Other: int list * int -> Choice<int,int,(int * int list),(int * int list),int>
val i: int
Fork me on GitHub