返回介绍

数学基础

统计学习

深度学习

工具

Scala

三、测试

发布于 2023-07-17 23:38:22 字数 3876 浏览 0 评论 0 收藏 0

  1. scalaFuture 的一个优势是它能帮你避免阻塞。

    在大多数 JVM 实现中,创建几千个线程之后,在线程之间的上下文切换会使得性能无法接受。通过避免阻塞,可以持有一组数量有限的线程,让它们不停地工作。

    尽管如此,Scala 也允许你在需要的时候阻塞线程(从而等待它的结果)。ScalaAwait 对象提供了等待 Future 结果的手段。

    
    
    xxxxxxxxxx
    import scala.concurrent.Await import scala.concurrent.duration._ val fut = Future{ Future{Thread.sleep(10000); 21/1} } val x = Await.result(fut, 15.seconds) // 阻塞调用,返回 21

    Await.result 接收一个 Future 和一个 Duration(表示 Await.result 最长等待多长时间等待Future 完成)。如果时间超过 Duration 但是 Future 尚未完成,则触发超时。

  2. 通常用线程阻塞来对异步代码进行测试。既然 Await.result 已经返回结果,那么就可以对这个结果进行测试:

    
    
    xxxxxxxxxx
    import scala.concurrent.Await import scala.concurrent.duration._ import org.scalatest.Matchers._ val fut = Future{ Future{Thread.sleep(10000); 21/1} } val x = Await.result(fut, 15.seconds) // 阻塞调用,返回 21 x should be (21) // 测试代码
  3. 也可以使用 ScalaTestScalaFutures 特质提供的阻塞结构。如ScalaFutureFuture 隐式添加的 futureValue 方法,该方法会阻塞直到 future 完成。

    • 如果 future 失败了,则 futureValue 方法会抛出 TestFailedException 来描述这个失败。
    • 如果 future 成功了,则 futureValue 方法会返回成功的结果。
    
    
    xxxxxxxxxx
    import org.scalatest.concurrent.ScalaFutures._ val fut = Future{ Future{Thread.sleep(10000); 21/1} } fut.futureValue should be (42) // futureValue 是阻塞的
  4. 虽然阻塞线程并进行测试没什么问题,但是如果能够不阻塞线程并异步执行测试,则和生产环境保持一致。为此,ScalaTest 3.0 添加了异步测试的风格。

    拿到 Future 之后,你并不是先阻塞然后对结果执行断言,而是将断言直接 mapfuture 上,然后返回 Future[Assertion]ScalaTest

    当这个 Future 的断言完成时,ScalaTest 会异步地将事件(测试成功、测试失败等)发送给测试报告程序。

    
    
    xxxxxxxxxx
    import org.scalatest.AsyncFunSpec import scala.concurrent.Future ​ class AddSpec extends AsyncFunSpec{ def addSoon(addends: Int*) : Future[Int] = Future{addends.sum} describe("addSoon"){ it("will compute a sum of ints"){ val futureSum:Future[Int] = addSoon(1,2,3) futureSum map { sum => assert(sum == 6)} // 将断言映射成 Future,然后返回 Future[Assertion] 给 ScalaTest } } }
  5. 异步测试的用例展示了处理 Future 的一般原则:一旦进入 Future 空间,就尽量呆在 Future 空间。不要对一个 Future 阻塞拿到结果后再继续进行计算,而是通过执行一系列的变换,并在每个变换返回新的 Future 以供下游进一步变换从而保持异步性。

    当需要从 Future 空间拿到结果时,则注册副作用,并在 Future 完成时异步执行。

    这种方式可以让你以最大限度的利用线程。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文