sbt test
概要
sbt [query / ] test [testname1 testname2] [ -- options ]
描述
test 任务提供编译和运行测试的方式。
默认情况下,sbt 2.x 中的 test 任务:
- 子项目并行。并行编译由 query 指定的相关子项目。
- 测试套件并行。将发现的测试套件映射为任务并并行执行。
- 增量测试。仅运行上次失败、从未运行,或 sbt 检测到测试或其依赖有变更的测试。
- 缓存。测试结果在机器范围内缓存,并可选择远程缓存。
测试的标准源位置为:
src/test/scala/中的 Scala 源src/test/java/中的 Java 源src/test/resources/中用于测试 classpath 的资源
测试中可通过 java.lang.Class 或 java.lang.ClassLoader 的 getResource 方法访问资源。
测试接口
sbt 为基于 JVM 的测试框架定义了通用接口,支持自动发现测试套件和并行执行。默认情况下 sbt 与 MUnit、ScalaTest、Hedgehog、ScalaCheck、Specs2、Weaver、ZIO Test 和 JUnit 4 集成;这意味着您只需将测试框架添加到 classpath 即可与 sbt 配合使用。例如,可通过将其声明为 libraryDependency 使用 MUnit:
lazy val munit = "org.scalameta" %% "munit" % "1.2.0"
libraryDependencies += munit % Test
上述中,Test 表示 Test 配置,意味着 MUnit 仅出现在测试 classpath 中,主源不需要它。
JUnit
JUnit 5 支持由 sbt-jupiter-interface 提供。要为项目添加 JUnit Jupiter 支持,请在项目主 build.sbt 文件中添加 jupiter-interface 依赖。
libraryDependencies += "com.github.sbt.junit" % "jupiter-interface" % "0.15.1" % Test
并将 sbt-jupiter-interface 插件添加到 project/plugins.sbt:
addSbtPlugin("com.github.sbt.junit" % "sbt-jupiter-interface" % "0.15.1")
JUnit 4 支持由 junit-interface 提供。请在项目主 build.sbt 文件中添加 junit-interface 依赖。
libraryDependencies += "com.github.sbt" % "junit-interface" % "0.13.3" % Test
测试过滤
在 sbt 2.x 中,test 任务接受以空格分隔的测试名称列表。例如:
> test example.ExampleSuite example.ExampleSuite2
示例输出:
> test example.ExampleSuite example.ExampleSuite2
[info] compiling 1 Scala source to /tmp/foo/target/out/jvm/scala-3.7.2/foo/backend ...
[info] compiling 2 Scala sources to /tmp/foo/target/out/jvm/scala-3.7.2/foo/test-backend ...
example.ExampleSuite:
+ addition 0.003s
example.ExampleSuite2:
+ subtraction 0.003s
[info] Passed: Total 2, Failed 0, Errors 0, Passed 2
[success] elapsed time: 3 s, cache 49%, 25 disk cache hits, 26 onsite tasks
也支持通配符:
> test *Example*
增量测试
除显式过滤外,test 任务仅运行满足以下条件之一的测试:
- 上次运行失败的测试
- 之前未运行过的测试
- 有一个或多个传递依赖(可能在不同项目中)被重新编译的测试。
完整测试
要运行未缓存的完整测试(如 sbt 1.x),请使用 testFull 任务。
其他任务
主源可用的任务通常也可用于测试源,但在命令行中需加 Test / 前缀,在 Scala 代码中也以 Test / 引用。这些任务包括:
Test / compileTest / consoleTest / consoleQuickTest / runTest / runMain
详见 sbt run 了解这些任务。
输出
默认情况下,每个测试源文件的日志会缓冲到该文件所有测试完成。可通过设置 logBuffered 禁用:
Test / logBuffered := false
测试报告
默认情况下,sbt 会为构建中所有测试生成 JUnit XML 测试报告,位于项目的 target/test-reports 目录。可通过禁用 JUnitXmlReportPlugin 来禁用此功能。
val myProject = (project in file(".")).disablePlugins(plugins.JUnitXmlReportPlugin)
选项
测试框架参数
测试框架参数可在命令行中通过 -- 分隔符传递给 test 任务。例如:
> test org.example.MyTest -- -verbosity 1
要在构建中指定测试框架参数,添加由 Tests.Argument 构造的选项:
Test / testOptions += Tests.Argument("-verbosity", "1")
要仅为特定测试框架指定:
Test / testOptions += Tests.Argument(TestFrameworks.ScalaCheck, "-verbosity", "1")
设置与清理
使用 Tests.Setup 和 Tests.Cleanup 指定设置和清理操作。它们接受 () => Unit 类型或 ClassLoader => Unit 类型的函数。接受 ClassLoader 的变体会接收用于运行测试的(或曾用于运行测试的)类加载器,可访问测试类和测试框架类。
示例:
Test / testOptions += Tests.Setup( () => println("Setup") )
Test / testOptions += Tests.Cleanup( () => println("Cleanup") )
Test / testOptions += Tests.Setup( loader => ... )
Test / testOptions += Tests.Cleanup( loader => ... )
禁用测试套件并行执行
默认情况下,sbt 在与自身相同的 JVM 中并行运行所有任务。由于每个测试套件映射为一个任务,测试默认也并行运行。要使给定项目内的测试串行执行:
Test / parallelExecution := false
注意,不同项目的测试仍可能并发执行。
过滤类
若您只想运行名称以 "Test" 结尾的测试类,使用 Tests.Filter:
Test / testOptions := Seq(Tests.Filter(s => s.endsWith("Test")))
Fork 测试
该设置:
Test / fork := true
指定所有测试将在单个外部 JVM 中执行。
可通过 testGrouping 键更精细控制测试如何分配到 JVM 以及传递哪些选项。
通过设置 Tags.ForkedTestGroup 标签的限制可控制同时运行的 fork JVM 数量,默认为 1。当组被 fork 时,无法为 Setup 和 Cleanup 操作提供实际测试类加载器。