Maa*_*mon 6 asynchronous scala future scalatest
我正在尝试使用 scalatest Asynchronous Test Suites,但除了设置超时的一些限制之外,我没有看到测试套件实际添加了什么。
我想知道是否有人精通 scalatest 异步测试,可以快速解释异步测试套件和org.scalatest.concurrent. 异步测试套件实际上添加了org.scalatest.concurrent什么?一种方法比另一种更好吗?
Mar*_*lic 12
我们比较了以下用于测试返回Futures 的代码的 ScalaTest 工具:
class AsyncSpec extends AsyncFlatSpec {
...
Future(3).map { v => assert(v == 3) }
...
}
Run Code Online (Sandbox Code Playgroud)
Future完成之前断言,即返回Future[Assertion]而不是AssertionFutures 按照它们开始的顺序执行和完成FuturesAwait,whenReadyFuture[Assertion]class ScalaFuturesSpec extends FlatSpec with ScalaFutures {
...
whenReady(Future(3) { v => assert(v == 3) }
...
}
Run Code Online (Sandbox Code Playgroud)
Future才能返回Assertionscala.concurrent.ExecutionContext.Implicits.global是用于并行执行的多线程池Assertionclass EventuallySpec extends FlatSpec with Eventually {
...
eventually { assert(Future(3).value.contains(Success(3))) }
...
}
Run Code Online (Sandbox Code Playgroud)
FuturesFutures时很可能会使用全局执行上下文scalatest-async-testing-comparison是演示两种执行模型差异的示例。
鉴于以下测试体
val f1 = Future {
val tmp = mutableSharedState
Thread.sleep(5000)
println(s"Start Future1 with mutableSharedState=$tmp in thread=${Thread.currentThread}")
mutableSharedState = tmp + 1
println(s"Complete Future1 with mutableSharedState=$mutableSharedState")
}
val f2 = Future {
val tmp = mutableSharedState
println(s"Start Future2 with mutableSharedState=$tmp in thread=${Thread.currentThread}")
mutableSharedState = tmp + 1
println(s"Complete Future2 with mutableSharedState=$mutableSharedState")
}
for {
_ <- f1
_ <- f2
} yield {
assert(mutableSharedState == 2)
}
Run Code Online (Sandbox Code Playgroud)
让我们考虑AsyncSpec反对的输出ScalaFuturesSpec
testOnly 示例.AsyncSpec:
Start Future1 with mutableSharedState=0 in thread=Thread[pool-11-thread-3-ScalaTest-running-AsyncSpec,5,main]
Complete Future1 with mutableSharedState=1
Start Future2 with mutableSharedState=1 in thread=Thread[pool-11-thread-3-ScalaTest-running-AsyncSpec,5,main]
Complete Future2 with mutableSharedState=2
Run Code Online (Sandbox Code Playgroud)testOnly 示例.ScalaFuturesSpec:
Start Future2 with mutableSharedState=0 in thread=Thread[scala-execution-context-global-119,5,main]
Complete Future2 with mutableSharedState=1
Start Future1 with mutableSharedState=0 in thread=Thread[scala-execution-context-global-120,5,main]
Complete Future1 with mutableSharedState=1
Run Code Online (Sandbox Code Playgroud)请注意在串行执行模型中如何使用相同的线程并按顺序完成期货。另一方面,在全局执行模型中,使用了不同的线程,并且Future2在 之前完成Future1,这导致共享可变状态的竞争条件,从而使测试失败。
在单元测试中,我们应该使用模拟子系统,其中返回的子系统Futures应该几乎立即完成,因此不需要Eventually在单元测试中。因此,选择是在异步样式和ScalaFutures. 两者之间的主要区别在于前者与后者不同,后者是非阻塞的。如果可能,我们不应该阻塞,所以我们应该更喜欢像AsyncFlatSpec. 更大的区别是执行模型。异步样式默认使用自定义串行执行模型,该模型在共享可变状态上提供线程安全,这与通常与ScalaFutures. 总之,我的建议是我们使用异步样式特征,除非我们有充分的理由不这样做。
| 归档时间: |
|
| 查看次数: |
2007 次 |
| 最近记录: |