如何让 SBT 并行运行测试套件?

Posted

技术标签:

【中文标题】如何让 SBT 并行运行测试套件?【英文标题】:How to make SBT run test suites in parallel? 【发布时间】:2020-02-22 12:43:26 【问题描述】:

我有一堆由 sbt 运行的集成测试,给定测试 N 个套件,每个套件有 1..M 个测试。 我设置了fork in IntegrationTest := true,但测试套件总是按顺序执行。根据文档,情况一定不是这样:测试套件应该同时执行。

测试套件是一个如下的类:

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

注意

我注意到所有测试都使用相同的池和线程运行,例如,pool-1-thread-1 用于所有测试。

sbt 版本:1.2.8 斯卡拉:2.12.8 操作系统:MacOS 10.15、Ubuntu 19.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: _*)

【问题讨论】:

欢迎来到 SO Nik,这似乎相关吗? ***.com/a/15753250/98057 你好,不,我认为这些是不同的问题。 【参考方案1】:

解决方案:

似乎有 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),

【讨论】:

【参考方案2】:

默认情况下,在分叉的 JVM 中执行的测试是按顺序执行的。请参阅 sbt testing docs 中的以下段落:

设置:

测试/分叉 := true

指定所有测试都将在单个外部 JVM 中执行。 请参阅分叉以配置分叉的标准选项。默认, 在分叉的 JVM 中执行的测试是按顺序执行的。更多控制 关于如何将测试分配给 JVM 以及将哪些选项传递给这些 可通过 testGrouping 键获得。

所以,你有两个选择:

    不要 fork JVM,默认情况下您的测试将并行运行 如果您想同时进行 fork 和 rut 测试,请阅读以下文档: https://www.scala-sbt.org/1.x/docs/Testing.html#Forking+tests

【讨论】:

我想按套件并行执行测试,但在套件内部按顺序执行。

以上是关于如何让 SBT 并行运行测试套件?的主要内容,如果未能解决你的问题,请参考以下文章

如何构建运行测试套件的 Maven 工件? “sbt 测试”如何工作?

如何在 Perl 测试套件中并行运行一些但不是所有测试?

如何并行运行机器人框架测试用例而不是并行测试套件?

如何在机器人框架中并行运行多个测试套件上的多个测试用例 | Python

如何使用 SBT Jenkins 插件运行特定测试以进行 ScalaTest 测试

如何在 TeamCity 中正确并行化我的测试套件?