I'm testing a REST API, and the code goes like this:
The code is currently in one rather huge FlatSpec
:
class RestAPITest extends FlatSpec
with Matchers
with ScalatestRouteTest
with SprayJsonSupport
I would like to chop the "Testing API a/b/..." parts out, to have the code more manageable. Trying to do that seems like a no-no: what's the type of it
- how to pass that on, etc. etc.
So, what's the recommended way to go about such stuff.
The a/b/... tests could be run in parallel, once the basic setup has succeeded.
I'm currently using assume
within the a/b/... tests to make them cancel if the initialization failed.
Should I look at "fixtures" or what for this? Have tried BeforeAndAfterAll
earlier, but didn't really get it working for me.
Thanks for the pointers / opinions. How do you keep your test suites short?
Adding as a new answer, so the differences are clear and the discussion above need not be removed. If I didn't do any typos, this should work (I did test it, and adopted in my project).
import org.scalatest._
/*
* Mix this trait into any specs that need 'TestA' to have been run first.
*/
trait TestAFirst {
// Reading a 'TestA' object's field causes it to be instantiated and 'TestA' to be executed (but just once).
//
val testASuccess = TestA.success
}
/*
* 'TestA' gets instantiated via the companion object explicitly (thus @DoNotDiscover)
* and creates a success value field. Otherwise, it's a test just like any other.
*/
@DoNotDiscover
class TestA private extends FlatSpec {
private var success = false // read once, by the companion object
behavior of "Root class"; {
it should "run prior to any of the B,C classes" in {
assert(true) // ... A tests
success = true
}
}
}
object TestA {
val success = {
val o= new TestA
o.execute
o.success // getting a value from the executed test ('.execute()' itself doesn't provide a status)
}
}
class TestB extends FlatSpec with TestAFirst {
behavior of "class B"; {
it should "run after A has been run" in {
assume(testASuccess)
assert(true) // ... B tests
}
}
}
class TestC extends FlatSpec with TestAFirst {
behavior of "class C"; {
it should "run after A has been run" in {
assume(testASuccess)
assert(true) // ... C tests
}
}
}