-
Notifications
You must be signed in to change notification settings - Fork 90
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Global fixtures #420
Comments
Thank you for reporting! It would be fantastic if we could add support for global fixtures. As discussed on Discord, one way to accomplish this is to extend Another way to accomplish this would be to register global fixtures by overriding a method name
|
After a closer look I am concerned this is more tricky than I originally expected. It's easy to acquire global resources but it's tricky to know when to close them. One workaround you can try today is to put the global resources on a Scala object and register a JVM shutdown hook. Make sure to enable the sbt setting object MyGlobalFixture {
private var i = 0
def message(): String = {
i += 1
s"message${i}"
}
Runtime.getRuntime
.addShutdownHook(new Thread {
override def run(): Unit = {
println(s"SHUTTING DOWN ${i}")
throw new RuntimeException("BOOM") // gets ignored
}
})
}
class GlobalFixtureSuite1 extends munit.FunSuite {
test("fixture1") {
println(MyGlobalFixture.message())
}
}
class GlobalFixtureSuite2 extends munit.FunSuite {
test("fixture2") {
println(MyGlobalFixture.message())
}
} The output from running both tests
If we want to avoid JVM shutdown hooks then it gets trickier because MUnit only has visibility into the execution of a single test suite. We can easily fix this problem for sbt since we control the test framework implementation, but I'm struggling to find a solution that would also work in IntelliJ, Gradle, and Maven. One workaround within the JUnit framework is to write a test suite in Java that aggregates several MUnit suites like this
The field |
@keirlawson would you be able to try out the workaround above and report if it works for your codebase? |
JUnit 5 has APIs that might make it possible to implement global fixtures, see
|
Here's a draft of a global fixture API that we could expose in MUnit trait GlobalFixture[A] {
def apply(): A
def beforeAllTestSuites(): Future[Unit]
def afterAllTestSuites(): Future[Unit]
} You would then register global fixtures just like regular fixtures abstract class FunSuite {
def munitFixtures: List[Fixture[_]]
+ def munitGlobalFixtures: List[GlobalFixture[_]]
}
object db extends GlobalFixture[DatabaseConnection] { ... }
class MySuite extends FunSuite {
+ override val munitGlobalFixtures = List(db)
test("connect-db") {
+ db().query("...")
}
}
|
I wasn't able to get this working for my particular code, however I suspect that was more to do with cats-effect Runtime weirdness than the approach not in principal being viable |
@keirlawson did you enable |
Yep |
@keirlawson Do you have a minimized example with cats-effect that I could try to reproduce? |
Not sure how helpful it is, but weaver-test implements something like this. Their architecture is very different though so I'm not sure if the design translates |
@Daenyth the biggest challenge is coming up with a solution that works in all clients (IntelliJ, Gradle, Maven, sbt). This requirement means we need to somehow work within the JUnit framework. There’s nothing in JUnit 4 that allows this from what I can tell but it’s easy to implement with JUnit 5 “TestFramework”. |
I have a requirement to run some tests in parallel (as they are slow end-to-end tests) however I'd like them to share resources. So far as I can see this is not presently possible with munit as there is no mechanism for fixtures shared by test suites.
The text was updated successfully, but these errors were encountered: