Scalatest或Specs2 - 在并行运行的测试中设置和拆除变量

时间:2013-04-24 21:17:58

标签: scala tdd bdd scalatest specs2

如果我需要为每个测试套件设置一些变量,是否可以以某种方式设置它们并让它们进入测试而无需为每个测试编写套件?

即,设置:

val actorRef = context.actorOf(Props(new MyTestDude))

拆解:

actorRef ! PoisonPill

如果我使用setup和teardown hook运行,我需要将actorref作为测试类中的一个字段,以便可以从setup方法访问它,但是我无法并行运行测试,因为每个人都将共享相同的状态。 / p>

2 个答案:

答案 0 :(得分:2)

根据您的信息,您可以使用AroundOutside implicit context在规范2中执行类似操作:

import org.specs2._
import execute._
import specification._

class s extends mutable.Specification {
  // this context will be used for each example
  implicit def withActor = new AroundOutside[ActorRef] { 

    // actor is passed to each example
    val actor = context.actorOf(Props(new MyTestDude)) 
    def outside = actor

    // execute the example code
    def around[R : AsResult](r: =>R) = {
      try AsResult(r)
      finally (actor ! PoisonPill)
    }
  }

  "My actor rules!" in { actor: ActorRef =>
     actor ! "very important message"
     ok
  }
}

答案 1 :(得分:1)

在Scalatest中,所有Suite子类都有一些处理方式,这在特定套件类的Scaladoc中有详细描述。

以下是使用FunSuite的示例,基于文档。 http://www.artima.com/docs-scalatest-2.0.M5b/#org.scalatest.FunSuite

class ExampleSuite extends fixture.FunSuite {

  case class F(actorRef: ActorRef)
  type FixtureParam = F

  def withFixture(test: OneArgTest) {

    val actorRef = context.actorOf(Props(new MyTestDude))
    val fixture = F(actorRef)

    try {
      withFixture(test.toNoArgTest(fixture)) // "loan" the fixture to the test
    }
    finally {
      actorRef ! PoisonPill
    }
  }

  test("My actor rules!") { f =>
    f.actorRef ! "very important message"
    assert( ... )
  }
}

另请注意,Akka有一个名为TestKit的ScalaTest特殊模块,它将使测试演员更容易。 http://doc.akka.io/docs/akka/snapshot/scala/testing.html