【问题标题】:Specs2 tests for activator's minimal-akka-scala-seed fails at times激活器的最小 akka-scala-seed 的 Specs2 测试有时会失败
【发布时间】:2016-01-08 02:58:45
【问题描述】:

我尝试使用scalatest 和specs2 测试乒乓球示例(来自激活器的minimal-akka-scala-seed)(我自己编写了specs2 测试;见下文)。

最大规模的总是过去。但是,specs2 测试并非始终通过(即,如果我多次重新运行相同的测试)。失败时,输出如下:

   [info] PingPongActorSpecs2
   [info] 
   [info] A Ping actor in specs2 should should
   [error]   ! send back a ping on a pong
   [error]    assertion failed: expected PingMessage(ping), found PongMessage(pong) (TestKit.scala:339)
   [error] akka.testkit.TestKitBase$class.expectMsg_internal(TestKit.scala:339)
   [error] akka.testkit.TestKitBase$class.expectMsg(TestKit.scala:315)
   [error] akka.testkit.TestKit.expectMsg(TestKit.scala:718)
   [error] com.example.PingPongActorSpecs2$$anonfun$1$$anonfun$apply$1$$anon$1$$anonfun$2.apply(PingPongActor2Spec.scala:27)
   [error] com.example.PingPongActorSpecs2$$anonfun$1$$anonfun$apply$1$$anon$1$$anonfun$2.apply(PingPongActor2Spec.scala:25)
   [error] akka.testkit.TestKitBase$class.within(TestKit.scala:296)
   [error] akka.testkit.TestKit.within(TestKit.scala:718)
   [error] akka.testkit.TestKitBase$class.within(TestKit.scala:310)
   [error] akka.testkit.TestKit.within(TestKit.scala:718)
   [error] com.example.PingPongActorSpecs2$$anonfun$1$$anonfun$apply$1$$anon$1.<init>(PingPongActor2Spec.scala:25)
   [error] com.example.PingPongActorSpecs2$$anonfun$1$$anonfun$apply$1.apply(PingPongActor2Spec.scala:23)
   [error] com.example.PingPongActorSpecs2$$anonfun$1$$anonfun$apply$1.apply(PingPongActor2Spec.scala:23)
   [info] 
   [info] A Pong actor in specs2 should should
   [error]   ! send back a pong on a ping
   [error]    assertion failed: expected PongMessage(pong), found PingMessage(ping) (TestKit.scala:339)
   [error] akka.testkit.TestKitBase$class.expectMsg_internal(TestKit.scala:339)
   [error] akka.testkit.TestKitBase$class.expectMsg(TestKit.scala:315)
   [error] akka.testkit.TestKit.expectMsg(TestKit.scala:718)
   [error] com.example.PingPongActorSpecs2$$anonfun$3$$anonfun$apply$2$$anon$2$$anonfun$4.apply(PingPongActor2Spec.scala:37)
   [error] com.example.PingPongActorSpecs2$$anonfun$3$$anonfun$apply$2$$anon$2$$anonfun$4.apply(PingPongActor2Spec.scala:35)
   [error] akka.testkit.TestKitBase$class.within(TestKit.scala:296)
   [error] akka.testkit.TestKit.within(TestKit.scala:718)
   [error] akka.testkit.TestKitBase$class.within(TestKit.scala:310)
   [error] akka.testkit.TestKit.within(TestKit.scala:718)
   [error] com.example.PingPongActorSpecs2$$anonfun$3$$anonfun$apply$2$$anon$2.<init>(PingPongActor2Spec.scala:35)
   [error] com.example.PingPongActorSpecs2$$anonfun$3$$anonfun$apply$2.apply(PingPongActor2Spec.scala:33)
   [error] com.example.PingPongActorSpecs2$$anonfun$3$$anonfun$apply$2.apply(PingPongActor2Spec.scala:33)
   [info] 
   [info] 
   [info] Total for specification PingPongActorSpecs2
   [info] Finished in 19 ms
   [info] 3 examples, 0 failure, 2 errors

我实现的specs2测试如下(非常类似于scalatest in the test folder of the minimal-akka-scala-seed):

 package com.example

 import org.specs2.mutable.SpecificationLike
 import org.specs2.specification.AfterAll

 import akka.actor.{ Actor, ActorSystem, Props }
 import akka.testkit.{ TestKit, ImplicitSender }

 class PingPongActorSpecs2(_system: ActorSystem) extends TestKit(_system) 
   with ImplicitSender 
   with SpecificationLike 
   with AfterAll {
   import scala.concurrent.duration._

   def this() = this(ActorSystem("MySpec"))

   override def afterAll {
     TestKit.shutdownActorSystem(system)
   }

   lazy val waitTime = 1 seconds

   "A Ping actor in specs2 should" >> {
     "send back a ping on a pong" >> {
        val pingActor = system.actorOf(PingActor.props)
        within (waitTime) {
           pingActor ! PongActor.PongMessage("pong")
           expectMsg(PingActor.PingMessage("ping"))
           true
        }
     }
   }

   "A Pong actor in specs2 should" >> {
    "send back a pong on a ping" >> {
      val pongActor = system.actorOf(PongActor.props)
        within (waitTime) {
          pongActor ! PingActor.PingMessage("ping")
          expectMsg(PongActor.PongMessage("pong"))
          true
        }
     }
   }
 }

我的库依赖如下:

 scalaVersion := "2.11.6"

 lazy val akkaVersion = "2.3.13"

 lazy val scalaTestVersion = "2.2.4"

 lazy val specs2Version = "3.6"

 libraryDependencies ++= Seq(
   "com.typesafe.akka" %% "akka-actor" % akkaVersion,
   "com.typesafe.akka" %% "akka-testkit" % akkaVersion % "test",
   "org.scalatest" %% "scalatest" % scalaTestVersion % "test",
   "org.specs2" %% "specs2-core" % specs2Version
 )

有人知道我在 specs2 测试中哪里搞砸了吗?

【问题讨论】:

    标签: scala specs2 typesafe-activator akka-testkit


    【解决方案1】:

    Specs2 规范同时执行示例,因此您的 2 个示例可能会相互交互。您可以为每个示例创建一个系统(昂贵),也可以使用 sequential 参数让您的测试按顺序执行:

    class PingPongActorSpecs2(_system: ActorSystem) extends TestKit(_system) 
       with ImplicitSender 
       with SpecificationLike 
       with AfterAll {
    
      import scala.concurrent.duration._
      sequential
    
      ... 
    }
    

    【讨论】:

    • 谢谢埃里克。这样可行。在有和没有顺序参数的情况下各跑 20 次。使用顺序参数,它通过了 20/20。如果没有顺序参数,它会通过 15/20。
    • 我还从ScalaTest doc 中发现,ScalaTest 并行运行测试套件的常规方法是并行运行不同的套件,但任何一个套件的测试都按顺序运行。 这解释了为什么 scalates 一直在过去。
    • 是的,这确实是 ScalaTest 和 specs2 的默认设置之间的一个主要区别。在 specs2 中默认并发的原因是首先鼓励测试隔离。
    猜你喜欢
    • 1970-01-01
    • 2017-05-24
    • 1970-01-01
    • 1970-01-01
    • 2014-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多