如何并行制作 SBT 运行 测试套件?
How to make SBT run test suites in parallel?
我有一堆由 sbt 进行的集成测试 运行ning,给定测试 N 套件,每个套件有 1..M 测试。
我设置了 fork in IntegrationTest := true
,但测试套件总是按顺序执行。根据文档,事实并非如此:测试套件应该同时执行。
测试套件是 class 如下:
class MyTestSuite1 extends FlatSpec with Matchers
...
it should "do A" {}
it should "do B" {}
class MyTestSuite2 extends FlatSpec with Matchers
...
it should "do C" {}
it should "do D" {}
问题
MyTestSuite1 和 MyTestSuiteN 按顺序执行(准确地说是按字母顺序)
期待
MyTestSuite1 和 MyTestSuiteM 并发执行
环境
.sbopts:
-J-Xms1G
-J-Xmx4G
-J-XX:MaxMetaspaceSize=512m
-J-Xss4M
注意
我注意到所有测试 运行ning 使用相同的池和线程,例如,pool-1-thread-1
用于所有测试。
sbt 版本:1.2.8
斯卡拉:2.12.8
os:MacOS 10.15,Ubuntu19.04
Scalatest 版本:3.2.0-SNAP10
尝试了 sbt v. 1.3.2 - 结果相同。
添加
testOptions in IntegrationTest += Tests.Argument(TestFrameworks.ScalaTest, "-P4"),
没有帮助。
============
更新
fork in(IntegrationTest, test) := true
在全球范围内工作,但我有 2 个项目,我想让它工作以保留项目的相对路径。
例如
lazy val `p1` = Project(id = "p1", base = file("./p1"))
.configs(IntegrationTest)
.settings(Defaults.itSettings: _*)
.settings(
fork in(IntegrationTest, test) := true,
...)
lazy val `p2` = Project(id = "p2", base = file("./p2"))
.configs(IntegrationTest)
.settings(Defaults.itSettings: _*)
.settings(
fork in(IntegrationTest, test) := true,
...)
不运行并行测试
相反,这个 运行 是并行的,但是,很明显,主目录设置为“。”而不是分别是“./p1”或“./p2”:
fork in(IntegrationTest, test) := true
lazy val `p1` = Project(id = "p1", base = file("./p1"))
.configs(IntegrationTest)
.settings(Defaults.itSettings: _*)
默认情况下,在分支 JVM 中执行的测试是按顺序执行的。请参考 sbt 测试文档中的以下段落:
The setting:
Test / fork := true
specifies that all tests will be executed in a single external JVM.
See Forking for configuring standard options for forking. By default,
tests executed in a forked JVM are executed sequentially. More control
over how tests are assigned to JVMs and what options to pass to those
is available with testGrouping key.
所以,你有两个选择:
- 不要分叉 JVM,您的测试将默认 运行 并行
- 如果你想分叉并同时进行常规测试,请阅读此文档:
https://www.scala-sbt.org/1.x/docs/Testing.html#Forking+tests
解决方案:
似乎有 testForkedParallel in IntegrationTest := true
选项完全符合我的需要 - 它为每个测试套件生成新的 JVM。
==============
备注:
所以,唯一的问题是现在它生成的 JVM 数量与所有可用 CPU 的数量一样多,我无法只收集测试并发性:
选项 1 - 将所有 sbt 进程集中到只有 4 个并行
concurrentRestrictions in Global := Seq(Tags.limitAll(4))
选项 2 - 什么都不做(测试在子项目中)
concurrentRestrictions in Global += Tags.limit(Tags.Test, 4),
我有一堆由 sbt 进行的集成测试 运行ning,给定测试 N 套件,每个套件有 1..M 测试。
我设置了 fork in IntegrationTest := true
,但测试套件总是按顺序执行。根据文档,事实并非如此:测试套件应该同时执行。
测试套件是 class 如下:
class MyTestSuite1 extends FlatSpec with Matchers
...
it should "do A" {}
it should "do B" {}
class MyTestSuite2 extends FlatSpec with Matchers
...
it should "do C" {}
it should "do D" {}
问题
MyTestSuite1 和 MyTestSuiteN 按顺序执行(准确地说是按字母顺序)
期待
MyTestSuite1 和 MyTestSuiteM 并发执行
环境
.sbopts:
-J-Xms1G
-J-Xmx4G
-J-XX:MaxMetaspaceSize=512m
-J-Xss4M
注意
我注意到所有测试 运行ning 使用相同的池和线程,例如,pool-1-thread-1
用于所有测试。
sbt 版本:1.2.8 斯卡拉:2.12.8 os:MacOS 10.15,Ubuntu19.04 Scalatest 版本:3.2.0-SNAP10
尝试了 sbt v. 1.3.2 - 结果相同。 添加
testOptions in IntegrationTest += Tests.Argument(TestFrameworks.ScalaTest, "-P4"),
没有帮助。
============
更新
fork in(IntegrationTest, test) := true
在全球范围内工作,但我有 2 个项目,我想让它工作以保留项目的相对路径。
例如
lazy val `p1` = Project(id = "p1", base = file("./p1"))
.configs(IntegrationTest)
.settings(Defaults.itSettings: _*)
.settings(
fork in(IntegrationTest, test) := true,
...)
lazy val `p2` = Project(id = "p2", base = file("./p2"))
.configs(IntegrationTest)
.settings(Defaults.itSettings: _*)
.settings(
fork in(IntegrationTest, test) := true,
...)
不运行并行测试
相反,这个 运行 是并行的,但是,很明显,主目录设置为“。”而不是分别是“./p1”或“./p2”:
fork in(IntegrationTest, test) := true
lazy val `p1` = Project(id = "p1", base = file("./p1"))
.configs(IntegrationTest)
.settings(Defaults.itSettings: _*)
默认情况下,在分支 JVM 中执行的测试是按顺序执行的。请参考 sbt 测试文档中的以下段落:
The setting:
Test / fork := true
specifies that all tests will be executed in a single external JVM. See Forking for configuring standard options for forking. By default, tests executed in a forked JVM are executed sequentially. More control over how tests are assigned to JVMs and what options to pass to those is available with testGrouping key.
所以,你有两个选择:
- 不要分叉 JVM,您的测试将默认 运行 并行
- 如果你想分叉并同时进行常规测试,请阅读此文档: https://www.scala-sbt.org/1.x/docs/Testing.html#Forking+tests
解决方案:
似乎有 testForkedParallel in IntegrationTest := true
选项完全符合我的需要 - 它为每个测试套件生成新的 JVM。
==============
备注:
所以,唯一的问题是现在它生成的 JVM 数量与所有可用 CPU 的数量一样多,我无法只收集测试并发性:
选项 1 - 将所有 sbt 进程集中到只有 4 个并行
concurrentRestrictions in Global := Seq(Tags.limitAll(4))
选项 2 - 什么都不做(测试在子项目中)
concurrentRestrictions in Global += Tags.limit(Tags.Test, 4),