我使用一个公共的单例对象在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上的测试套件之间共享数据?有些数据需要几分钟来计算,而且重复计算它们很烦人。
2条答案
按热度按时间hwamh0ep1#
默认情况下,为了提高速度,sbt等构建工具会并行执行测试。在Scala. js世界中,这是通过生成多个JavaScript VM来实现的;由于单独的JS VM不共享内存,因此代码中的每个顶级
object
都为每个JS VM示例化一次。这些对象的初始化应该是并行执行的,所以在大多数情况下,你不会注意到这些独立的示例会增加初始化时间。但是,多任务处理是复杂的,所以在某些情况下,事情可能会变慢。
您可以通过在构建工具中禁用并行测试执行来强制执行单个初始化。在sbt中,您可以使用以下设置来执行此操作:
这将确保只使用一次JS VM。但这也意味着测试套件中的所有测试都将按顺序运行,而不会利用多个核心。
luaexgnf2#
您可以使用Suites对多个套件进行分组-另请参阅Group ScalaTest tests and run in order。任何此类组都作为单个套件运行,因此使用单个VM。
不过,还有一件事要做,因为
@DoNotDiscover
似乎不能在Scala.js上工作。您需要阻止SBT运行单个套件,您可以在SBT中使用Test / testOptions += Tests.Filter(s => !s.endsWith("SubTest"))
并相应地命名您的套件。以下是来源:
输出为: