【问题标题】:run scalatest with separate jvm per suite每个套件使用单独的 jvm 运行 scalatest
【发布时间】:2020-07-16 09:07:14
【问题描述】:

我想从 sbt 并行运行测试套件,但每个套件都有自己的专用 jvm。
(在我的项目中,每个 jvm 有一个资源,不能从不同的线程并行使用)

这是我的测试设置:

import java.lang.management.ManagementFactory
import org.scalatest.FunSuite

trait BaseTest extends FunSuite {

  test("test1") {
    println(f"process_id: ${ManagementFactory.getRuntimeMXBean.getName} -  thread_id: ${Thread.currentThread.getId}")
    Thread.sleep(5000)
  }
}

class Test1 extends BaseTest
class Test2 extends BaseTest
class Test3 extends BaseTest

这些是我在 sbt 中尝试过的设置:

logBuffered in Test := false //make the logs nicer

parallelExecution in Test := true
fork in Test := true
testForkedParallel in Test := true
concurrentRestrictions in Global := Seq(Tags.limit(Tags.ForkedTestGroup, 4), Tags.limit(Tags.Test, 4))

这是我运行测试时打印的内容:

process_id: 16676@host - thread_id: 13
process_id: 16676@host - thread_id: 14
process_id: 16676@host - thread_id: 12

测试在不同的线程中运行,但都在同一个进程中。

我有办法让每个套件都有自己的 jvm?

【问题讨论】:

    标签: scala sbt scalatest


    【解决方案1】:

    这是我第一次听说设置。一般来说,这很难,因为所有工具都试图尽可能地重用 JVM 来保持它的温暖。

    你可以做一些像跑步这样的事情:

    sbt -no-colors --error "print test:definedTests"
    

    获取测试套件列表。如果我为我的一个项目运行它,我可以得到类似的东西:

    chimneyJVM / Test / definedTests
            Vector(Test io.scalaland.chimney.PatcherSpec : subclass(true, utest.TestSuite), Test io.scalaland.chimney.PBTransformationSpec : subclass(true, utest.TestSuite), Test io.scalaland.chimney.DslSpec : subclass(true, utest.TestSuite), Test io.scalaland.chimney.DslFSpec : subclass(true, utest.TestSuite), Test io.scalaland.chimney.IssuesSpec : subclass(true, utest.TestSuite), Test io.scalaland.chimney.JavaBeansSpec : subclass(true, utest.TestSuite))
    chimneyJS / Test / definedTests
            Vector(Test io.scalaland.chimney.PatcherSpec : subclass(true, utest.TestSuite), Test io.scalaland.chimney.PBTransformationSpec : subclass(true, utest.TestSuite), Test io.scalaland.chimney.DslSpec : subclass(true, utest.TestSuite), Test io.scalaland.chimney.DslFSpec : subclass(true, utest.TestSuite), Test io.scalaland.chimney.IssuesSpec : subclass(true, utest.TestSuite), Test io.scalaland.chimney.JavaBeansSpec : subclass(true, utest.TestSuite))
    chimneyCatsJVM / Test / definedTests
            Vector(Test io.scalaland.chimney.cats.CatsValidatedSpec : subclass(true, utest.TestSuite))
    chimneyCatsJS / Test / definedTests
            Vector(Test io.scalaland.chimney.cats.CatsValidatedSpec : subclass(true, utest.TestSuite))
    Test / definedTests
            Vector()
    

    此输出可由 AWK 或 Python 脚本之类的东西解析,以获取按项目分组的测试套件列表。

    下一步,您可以为每个项目套件运行:

    sbt $project/testOnly $suite
    

    这将在单独的进程中运行每个套件。

    但是,这些进程中的每一个都会在文件系统上使用相同的锁,以确保其他一些进程不会从它下面拉地毯(合理),但是 - 即使您之前运行 test:compile 以避免同步关于编译——这会导致一些我只能认为是无效的、脆弱的混乱。每个进程都将重新分配内存(对于大量的套件,这将占用大量内存),初始化所有内容,所有进程都将争夺对相同资源的访问权限,并且所有进程都必须从头开始预热 JVM。我敢打赌,除非你有一个非常奇怪的用例,否则这种设置会比在一个 JVM 中按顺序运行套件要慢。

    【讨论】:

    • 这是一个有趣的想法,我将尝试将其作为 sbt 任务而不是脚本运行。并且只是为了澄清我的设置,只要运行是顺序的,所有套件都可以在同一个 jvm 中运行。问题是并行运行它们时。所以我真的不需要每个套件 1 个 jvm,它也可以是 n 个单独的实例,每个实例运行一批套件
    猜你喜欢
    • 2017-05-22
    • 2011-02-22
    • 2020-07-19
    • 2016-11-07
    • 2018-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-13
    相关资源
    最近更新 更多