Skip to content

Instantly share code, notes, and snippets.

@derekwyatt
Created July 18, 2012 20:51
Show Gist options
  • Save derekwyatt/3138807 to your computer and use it in GitHub Desktop.
Save derekwyatt/3138807 to your computer and use it in GitHub Desktop.
Scalatest Fixtures and Akka - parallel fixture isolation - sequential fixture isolation - and no fixture
// Examples showing how to use the specification helpers
//
import akka.actor.ActorSystem
import akka.testkit.{TestKit, ImplicitSender}
import org.scalatest.{WordSpec, BeforeAndAfterAll}
import org.scalatest.matchers.MustMatchers
// Sequentially runs the tests, isolating the Fixture in each test. The Fixture carries the TestKit
// so each test gets its own ActorSystem
class MyAkkaTestSpec extends SequentialAkkaSpecWithIsolatedFixture {
type Fixture = AkkaFixture
def createAkkaFixture(): Fixture = new AkkaFixture
"MyAkkaTest" should {
"do something with a fixture" in { fixture => import fixture._
testActor must be (testActor)
}
}
}
// Same thing here, but more proof of that.
// The mutable junk isn't polluted between tests because there are separate fixtures per test
class MyAkkaTestSpec2 extends SequentialAkkaSpecWithIsolatedFixture {
type Fixture = MyFixture
class MyFixture extends AkkaFixture {
val someString = "Hithere"
val someInt = 5
var somethingMutable = 80000
}
def createAkkaFixture(): Fixture = new MyFixture
"MyAkkaTest" should {
"do something with a fixture" in { fixture => import fixture._
testActor must be (testActor)
someString must be ("Hithere")
someInt must be (5)
}
"muck with mutable data in the fixture" in { fixture => import fixture._
somethingMutable = 20
somethingMutable must be (20)
}
"see that mutable data unaltered" in { fixture => import fixture._
somethingMutable must be (80000)
}
}
}
import akka.actor.{Actor, ActorSystem, ActorRef, Props}
import akka.testkit.{TestKit, ImplicitSender}
import java.util.concurrent.atomic.AtomicInteger
import org.scalatest.{fixture, WordSpec, BeforeAndAfterAll, ParallelTestExecution}
import org.scalatest.matchers.MustMatchers
object ParallelAkkaTest {
val sysId = new AtomicInteger()
}
// Runs each individual test in parallel. Only possible with Fixture isolation
trait ParallelAkkaSpec extends fixture.WordSpec with MustMatchers with ParallelTestExecution {
import ParallelAkkaTest._
type Fixture <: AkkaFixture
type FixtureParam = Fixture
class AkkaFixture extends TestKit(ActorSystem("Parallel-%d".format(sysId.incrementAndGet())))
with ImplicitSender
def createAkkaFixture(): Fixture
override def withFixture(test: OneArgTest) {
val sys = createAkkaFixture()
try {
test(sys)
} finally {
sys.system.shutdown()
}
}
}
object SequentialAkkaSpecWithIsolatedFixture {
val sysId = new AtomicInteger()
}
// Runs each test sequentially but provides fixture isolation
trait SequentialAkkaSpecWithIsolatedFixture extends fixture.WordSpec with MustMatchers {
import SequentialAkkaSpecWithIsolatedFixture._
type Fixture <: TestKit
type FixtureParam = Fixture
class AkkaFixture extends TestKit(ActorSystem("WithIsoFix-%d".format(sysId.incrementAndGet())))
with ImplicitSender
def createAkkaFixture(): Fixture
override def withFixture(test: OneArgTest) {
val sys = createAkkaFixture()
try {
test(sys)
} finally {
sys.system.shutdown()
}
}
}
object SequentialAkkaSpec {
val sysId = new AtomicInteger()
}
// Boring ol' standard stuff :)
class SequentialAkkaSpec extends TestKit(ActorSystem("Sequential-%d".format(SequentialAkkaSpec.sysId.incrementAndGet())))
with ImplicitSender
with WordSpec
with MustMatchers
with BeforeAndAfterAll {
override def afterAll() {
system.shutdown()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment