haf / expecto

A smooth testing lib for F#. APIs made for humans! Strong testing methodologies for everyone!
Apache License 2.0
663 stars 96 forks source link

Howto use teardown on testlist or testfixure #409

Closed brase closed 3 years ago

brase commented 3 years ago

Hi,

I need a teardown function called after all tests of a testfixture or a testlist finished. I tried to use a disposable but I have no idea where to put it. Am I doing something wrong or is there no chance to achieve something like this?

Here is my example code:

[<Tests>]
let otherTests =
    let testDb = testDbName TestDbId
    let oneTimeSetup() =
        printfn "OneTimeSetup"
        restoreTestDbScript testDb "C:\\tmp\\snapshot.bak"
        |> executeCmd

    let oneTimeTearDown() =
        let disposable = { new System.IDisposable with
                            member this.Dispose() =
                                printfn "disposed!"
                                dropTestDbScript testDb
                                |> executeCmd
                             }
        disposable

    testList "With OneTimeSetup and OneTimeTearDown" [
        let x = lazy oneTimeSetup()

        let withDatabase f () =
            x.Force()
            use db = connectionString testDb |> connect
            let r = f db
            r

        yield! testFixture withDatabase [
            "Runs query against test db",
                (fun db ->
                    printfn "Testrun1"
                    let results = Queries.getSomething db (System.Guid.Parse("8e5614f7-b437-424f-b3bd-8d515e4087b4"))
                                  |> Async.RunSynchronously

                    Expect.hasLength results 23 "Should return the right amount")

            "Runs another query against test db",
                (fun db ->
                    printfn "Testrun2"
                    let results = Queries.getSomething db (System.Guid.Parse("8e5614f7-b437-424f-b3bd-8d515e4087b4"))
                                  |> Async.RunSynchronously

                    Expect.hasLength results 23 "Should return the right amount")
        ]
    ]
brase commented 3 years ago

Used the workaround with the additional test at the end but had to change it to sequenced. (source: https://github.com/haf/expecto/issues/352#issuecomment-541075223)

Is there any other option?

haf commented 3 years ago

There are many ways to model it, but I'd make it two testLists with the outer one setting up and tearing down and being sequenced, the the middle test being an inner testList with all your tests. This is probably the easiest version.

You can also program with standard parallel/concurrent programming primitives, such as countdown latch and lazy and such, counting down each test once it fails/succeeds and when the latch reaches zero, killing the database.

brase commented 3 years ago

Thank you!

There are many ways to model it, but I'd make it two testLists with the outer one setting up and tearing down and being sequenced, the the middle test being an inner testList with all your tests. This is probably the easiest version.

Will the inner tests then run parallel or sequenced?

haf commented 3 years ago

In parallel

brase commented 3 years ago

Thank you!