【问题标题】:Scalatest - how to create parallel test at runtimeScalatest - 如何在运行时创建并行测试
【发布时间】:2019-03-11 20:43:47
【问题描述】:

运行

package com.thron.qa.tests

import org.scalatest.{FunSuite, ParallelTestExecution}
import org.scalatest.concurrent.Eventually

class ParallelRuntimeTest extends FunSuite with Eventually with ParallelTestExecution{

  Vector.range(0,10).foreach(iteration => {
    test ("test number  n " + iteration.toString) {
      succeed
    }
  })

}

我获得运行时测试创建:对向量的迭代构建到测试,并且每个测试都具有成功状态,如您在 Idea Ide 中看到的那样

现在,我想并行化这些测试

通常我使用 .par 来获得操作的并行化, 所以代码变成了

Vector.range(0,10).par.foreach(iteration => {
    test ("test number  n " + iteration.toString) {
      succeed
    }
  })

但在这种情况下, 我收到此错误:

异常或错误导致运行中止:两个线程试图 修改 FunSuite 的内部数据,只能由 构造对象的线程。这可能意味着一个子类 允许 this 引用在构造过程中逃逸,还有一些 其他线程试图调用“testsFor”或“test”方法 第一个线程完成其构造之前的对象。 java.util.ConcurrentModificationException:两个线程试图 修改 FunSuite 的内部数据,只能由 构造对象的线程。这可能意味着一个子类 允许 this 引用在构造过程中逃逸,还有一些 其他线程试图调用“testsFor”或“test”方法 第一个线程完成其构造之前的对象。

如何在运行时创建测试并以并行方式运行?

谢谢

【问题讨论】:

    标签: scala scalatest


    【解决方案1】:

    test 命令不运行任何测试。它只是注册一个测试用例,并为其附加一个字符串名称。它不需要任何资源,并且基本上是即时的。因此,没有必要并行注册测试用例。正如您的错误消息所示,无论如何也无法并行注册它们。

    按顺序创建您的测试,它们将自动并行运行:

    import org.scalatest.{FunSuite, ParallelTestExecution}
    import org.scalatest.concurrent.Eventually
    
    class ParallelRuntimeTest 
    extends FunSuite 
       with Eventually 
       with ParallelTestExecution {
    
      for (i <- (0 to 59)) {
        test ("test number  n " + i) {
          Thread.sleep(1000)
          succeed
        }
      }
    
    }
    

    如果你测试它,你会注意到它大约需要 15 秒而不是一分钟(我认为这是因为用于测试的默认线程数是 4,所以 60 / 4 = 15)。

    【讨论】:

    • 是的。我的问题是intellij idea ide,它不会以并行方式执行测试。所以我“强制” ide 搜索 sbt 默认执行的并行性。谢谢。
    【解决方案2】:

    正如@Andrey Tyukin 所提到的,默认情况下,sbt 会在与 sbt 本身相同的 JVM 中并行运行所有任务。因为每个测试都映射到一个任务,所以默认情况下测试也是并行运行的。

    我们可以关闭多项目构建的并行执行测试,如下所示。

    parallelExecution in Test := false,
    parallelExecution in IntegrationTest := false
    

    使用 ParallelTestExecution 和“sbt test”-scalaTest 3.0.x (https://github.com/scalatest/scalatest/issues/898) 似乎存在问题。但是,此问题的解决方法是在 Overriding Distributor 中。

    class Example extends FunSpec with ParallelTestExecution with StressTest {
      describe("Example") {
        for (i <- 1 to poolSize) {
          it(s"test ${i} should run in parallel") {
            info(s"example ${i} start")
            Thread.sleep(5000)
            info(s"example ${i} end")
          }
        }
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2013-03-23
      • 2019-12-18
      • 2014-04-28
      • 1970-01-01
      • 2014-09-23
      • 2011-02-10
      • 2014-07-26
      • 1970-01-01
      • 2014-09-11
      相关资源
      最近更新 更多