You can require the entire toolkit in a single line:
//> using toolkit latest
MUnit, being a testing framework, is only available in test files: files in a test
directory or ones that have the .test.scala
extension. Refer to the Scala CLI documentation to learn more about the test scope.
Alternatively, you can require just a specific version of MUnit:
//> using dep org.scalameta::munit:1.0.0-M7
In your build.sbt file, you can add the dependency on toolkit-test:
lazy val example = project.in(file("."))
.settings(
scalaVersion := "3.3.3",
libraryDependencies += "org.scala-lang" %% "toolkit-test" % "0.1.7" % Test
)
Here the Test
configuration means that the dependency is only used by the source files in src/test
.
Alternatively, you can require just a specific version of MUnit:
libraryDependencies += "org.scalameta" %% "munit" % "1.0.0-M7" % Test
In your build.sc file, you can add a test
object extending Tests
and TestModule.Munit
:
object example extends ScalaModule {
def scalaVersion = "3.3.3"
object test extends Tests with TestModule.Munit {
def ivyDeps =
Agg(
ivy"org.scala-lang::toolkit-test:0.1.7"
)
}
}
Alternatively, you can require just a specific version of MUnit:
ivy"org.scalameta::munit:1.0.0-M7"
Asynchronous tests
In Scala, it’s common for an asynchronous method to return a Future
.
MUnit offers special support for Future
s.
For example, consider an asynchronous variant of a square
method:
import scala.concurrent.{ExecutionContext, Future}
object AsyncMathLib {
def square(x: Int)(implicit ec: ExecutionContext): Future[Int] =
Future(x * x)
}
import scala.concurrent.{ExecutionContext, Future}
object AsyncMathLib:
def square(x: Int)(using ExecutionContext): Future[Int] =
Future(x * x)
A test itself can return a Future[Unit]
.
MUnit will wait behind the scenes for the resulting Future
to complete, failing the test if any assertion fails.
You can therefore write the test as follows:
// Import the global execution context, required to call async methods
import scala.concurrent.ExecutionContext.Implicits.global
class AsyncMathLibTests extends munit.FunSuite {
test("square") {
for {
squareOf3 <- AsyncMathLib.square(3)
squareOfMinus4 <- AsyncMathLib.square(-4)
} yield {
assertEquals(squareOf3, 9)
assertEquals(squareOfMinus4, 16)
}
}
}
// Import the global execution context, required to call async methods
import scala.concurrent.ExecutionContext.Implicits.global
class AsyncMathLibTests extends munit.FunSuite:
test("square") {
for
squareOf3 <- AsyncMathLib.square(3)
squareOfMinus4 <- AsyncMathLib.square(-4)
yield
assertEquals(squareOf3, 9)
assertEquals(squareOfMinus4, 16)
}
The test first asynchronously computes square(3)
and square(-4)
.
Once both computations are completed, and if they are both successful, it proceeds with the calls to assertEquals
.
If any of the assertion fails, the resulting Future[Unit]
fails, and MUnit will cause the test to fail.
You may read more about asynchronous tests in the MUnit documentation.
It shows how to use other asynchronous types besides Future
.