如何在Scala.js测试套件之间共享数据?

z2acfund  于 2023-03-30  发布在  Scala
关注(0)|答案(2)|浏览(130)

我使用一个公共的单例对象在ScalaTest套件之间共享数据。在JVM上运行时,这很好,但令我惊讶的是,它在Scala.js上失败了。在Scala.js上,似乎每个套件都使用了一个新的程序示例,并且单例对象没有共享。
考虑以下代码:

import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers

object SharedTestData {
  var useCount = 0

  def useMe(): Int = {
    useCount += 1
    useCount
  }
}

class ATest extends AnyFlatSpec with Matchers {
  "This" should "pass" in {
    val used = SharedTestData.useMe()
    info(s"Used $used times")
  }
}

class BTest extends AnyFlatSpec with Matchers {
  "This" should "pass as well" in {
    val used = SharedTestData.useMe()
    info(s"Used $used times")
  }
}

项目配置为Scala.js的sbt test的输出是:

[info] BTest:
[info] This
[info] - should pass as well
[info]   + Used 1 times
[info] ATest:
[info] This
[info] - should pass
[info]   + Used 1 times
[info] Run completed in 422 milliseconds.
[info] Total number of tests run: 2

有没有什么技术可以让我在Scala.js上的测试套件之间共享数据?有些数据需要几分钟来计算,而且重复计算它们很烦人。

hwamh0ep

hwamh0ep1#

默认情况下,为了提高速度,sbt等构建工具会并行执行测试。在Scala. js世界中,这是通过生成多个JavaScript VM来实现的;由于单独的JS VM不共享内存,因此代码中的每个顶级object都为每个JS VM示例化一次。
这些对象的初始化应该是并行执行的,所以在大多数情况下,你不会注意到这些独立的示例会增加初始化时间。但是,多任务处理是复杂的,所以在某些情况下,事情可能会变慢。
您可以通过在构建工具中禁用并行测试执行来强制执行单个初始化。在sbt中,您可以使用以下设置来执行此操作:

.settings(
  ...
  Test / parallelExecution := false,
)

这将确保只使用一次JS VM。但这也意味着测试套件中的所有测试都将按顺序运行,而不会利用多个核心。

luaexgnf

luaexgnf2#

您可以使用Suites对多个套件进行分组-另请参阅Group ScalaTest tests and run in order。任何此类组都作为单个套件运行,因此使用单个VM。
不过,还有一件事要做,因为@DoNotDiscover似乎不能在Scala.js上工作。您需要阻止SBT运行单个套件,您可以在SBT中使用Test / testOptions += Tests.Filter(s => !s.endsWith("SubTest"))并相应地命名您的套件。
以下是来源:

@DoNotDiscover
class ASubTest extends AnyFlatSpec with Matchers {
  "This" should "pass" in {
    val used = SharedTestData.useMe()
    info(s"Used $used times")
  }
}

@DoNotDiscover
class BSubTest extends AnyFlatSpec with Matchers {
  "This" should "pass as well" in {
    val used = SharedTestData.useMe()
    info(s"Used $used times")
  }
}

class MySuite extends Suites(new ASubTest, new BSubTest)

输出为:

[info] ASubTest:
[info] This
[info] - should pass
[info]   + Used 1 times
[info] BSubTest:
[info] This
[info] - should pass as well
[info]   + Used 2 times

相关问题