Open forki opened 5 years ago
module End2End.Program
open Fable.Mocha
let allTests =
testList "End2End tests" [
SoundCheck.allTests
]
promise {
printfn "Init"
do! TestHelper.init()
Mocha.runTests allTests |> ignore
printfn "Cleanup"
do! TestHelper.cleanup()
printfn "Done"
}
|> ignore
this seems to work. But is it the correct way?
ok it's not working. it's not running my tests
Hello @forki, I will take a look at it when I am back home after work. Meanwhile maybe you could try out the following:
[<Emit("before($0)")>]
let before (callback: unit -> Promise<unit>) = jsNative
[<Emit("after($0)")>]
let after(callback: unit -> Promise<unit>) = jsNative
let allTests = testList "End2End tests" [ SoundCheck.allTests ]
before (fun () -> TestHelper.init())
Mocha.runTests allTests |> ignore
after (fun () -> TestHelper.cleanup())
This should do the setup/tear down according to Mocha's API but you should be able to do it manually on a per-test basis by writing a helper function around testCasePromise
that takes an IDisposable
and does the setup/tear down internally.
In any case, please try it out and let me know how it goes!
yes that works!
in other words: would be cool to have the following in the box
[<Emit("before($0)")>]
let before (callback: unit -> Promise<unit>) = jsNative
[<Emit("after($0)")>]
let after(callback: unit -> Promise<unit>) = jsNative
[<Emit("beforeEach($0)")>]
let beforeEach (callback: unit -> Promise<unit>) = jsNative
[<Emit("afterEach($0)")>]
let afterEach (callback: unit -> Promise<unit>) = jsNative
Thoth.Fetch
is using mocha
for the tests. I don't use yet Fable.Moche
so I have my own bindings in it. I am writing just this just as another reference.
The difference I see is that I use unit -> unit
instead of Promise<unit>
, but it's not a big deal could use Promise<unit>
if mocha support it too.
@forki Yeah we could add those here but I am not sure if there is a better syntax to match Expecto's API and I don't know how far we want to stay compatible with it. @TheAngryByrd Do you have any ideas on the matter?
could use Promise
if mocha support it too.
@MangelMaxime Mocha supports it indeed, but I guess if I implement it, I would implement both unit -> unit
and unit -> Promise<unit>
using function overloads
I think as long as we don't touch the current API, any additions we make wouldn't affect it. (cc @AnthonyLloyd).
I've added my own helper functions to do similar things with setup/teardowns and IDisposables, so I think it's a good idea to add more if we can.
Maybe a slightly different but longer discussion is we need to break this into two libraries, Fable.Mocha which has exclusive wrappers for Mocha stuff and a Fable.Mocha.Expecto library which tries to keep an API compatible with Expecto.
Thinking about it, IDisposable
might not be a good idea here since Dispose
is a synchronous call. I'm not sure if F#/Fable has a story around IAsyncDisposable yet.
I am writing test for a Database library and it would be really useful to have before
, beforeEach
, after
, afterEach
available in the library.
For example, it would make it possible to setup the database or clean it after running the tests. Right now, we can only have a before
and after
at the top level of the application as Fable.Mocha is using an internal "representation" to handle what needs to be done.
Is there plan for adding those functions? Should someone try to contribute it? If yes, what would be the way to go?
@MangelMaxime PRs are always welcome. I think implementing something like Test fixtures from Expecto would be a good way to go, what do you think?
I suppose Test fixtures is something use to "mock" part of the application. Like if you want to keep the client connection or have a file based database like sqlite for exemple.
In my case, I would need the function I listed to prepared and clean the database for the tests. For example, it would allow me to create a schema, populate it with some data, etc. and then remove it from the database to maintain the database in a "neutral" state.
I don't think Expecto have an equivalent to what Fable.Mocha offer. The closer thing I see is: https://github.com/haf/expecto#setup-and-teardown where it is actually "just code" doing the job. I need to do more test locally to see if the Expecto approach can work and be an alternative to adding beforeEach
, afterEach
, etc. Because, I suppose Fable.Mocha doesn't aim to provide 100% of the Mocha API but probably more the sweet spot allowing the user to switch between Expecto and Fable.Mocha easily. I can be wrong ^^
Second though, because Fable.Mocha is a DSL on top of Mocha and does some code "transformation" I don't think I can have a a function called at the beginning and the end of a testList
block.
Still need to test the beforeEach
, afterEach
case.
At work I just implemented a function that allows for a setup/tear down to a testList
for Expecto. I’d be willing to share that implantation (when I get to my computer) and see if aligning on the same signature is possible.
open System
open Expecto
open FSharp.Data.Adaptive
let integrationTestFixtureList name oneTimeSetup tests =
let myBase = cval Unchecked.defaultof<'a>
let setupTest = testCaseAsync "Setup" <| async {
let! result = oneTimeSetup
myBase.UpdateTo result
}
let teardownTest = testCaseAsync "Teardown" <| async {
// match box myBase with
// | :? IDisposable as d -> d.Dispose()
// | :? IAsyncDisposable as d -> do! d.DisposeAsync().AsTask() |> Async.AwaitTask
// | _ -> ()
// (myBase :> IDisposable).Dispose()
do! (myBase.Value :> IAsyncDisposable).DisposeAsync().AsTask() |> Async.AwaitTask
}
let tests = [
setupTest
yield! tests |> Seq.map(fun t -> t myBase)
teardownTest
]
testSequencedGroup name (testListConditional (fun () -> runIntegrationTests) name tests)
I create a setup and teardown test set each. I created a specific setup test because I needed the setup to be lazy, otherwise it would try to run at testList enumeration which would cause it to run even if it tests were to be skipped. At work I ended up using FSharp.Data.Adaptive
for this but we might be able to get away with a MailboxProcessor and inject a lazy Async<'MySetupType>
. For the teardown I went with IAsyncDisposeable
but I'm not completely tied to that implementation either. I have IDiseposeable
for other ideas/usages.
Usage:
type DbConnections = {
ConnStr : string
Props : Sql.SqlProps
}
let setup = async {
let connStr = getFromEnvVar("TEST_CONNECTION_STRING")
let props = Sql.connect connStr
return {
ConnStr = connStr
Props = props
}
}
let testList =
integrationTestFixtureList "Some Database Stuff" setup [
fun (conn : cval<AssetExpirationBase>) -> testCaseAsync "Test 1" <| async {
let conn = conn.Value
let expected = insertTestUser "13" conn.Props
let actual = Repository.getUser conn.Props "13"
Expect.equal actual expected ""
}
]
I haven't made this suggestion to Expecto proper as of yet since we're still trying it at work and I'd like it to be robust before I do.
Hi,
I have a promise setup and teardown function that I have to run. Any ideas how to do it? Of course I can't do runsync as in .NET code.