I am trying to write a bunch of test codes against a Java class library and I am using specs2 on Scala.
I have a group of test cases that should be ran for all the subclasses of class T, but could not figure out the best way to implement this.
Coming from Ruby, I naturally sought something like *shared_examples_for* macro as in Rspec, but there seems to be no such thing in specs2.
Then I thought, subclassing my own Specification subclass with test cases may be one way to go.
Is there any tidier solution to this?
You can find an example of shared examples in the User Guide. Basically this uses the fact that you can define a method taking a specific instance to test and declare examples for it (see the nonEmptyStack
method).
If this helps let me kickstart you with a quick example using a mutable Specification
:
import org.specs2._
class SubclassesSpec extends mutable.Specification {
"These examples must pass for all subclasses" >> {
subclasses foreach { subclass => examples(subclass) }
}
/** @return instances of subclasses of type T where T is
* the supertype of the classes you want to test */
def subclasses: Seq[T] = ...
/** @return examples parameterized by a specific instance */
def examples(t: T) = {
"this is the first example" >> {
// use t here
}
"this is the second example" >> {
// use t here
}
}
}
The only thing you need to check before you do that is the possible side-effects between examples. In the specification above, all the examples are executed concurrently and they share the same object. If that creates any issue, you can either:
add sequential
at the top of the specification to avoid concurrency
change subclasses
and examples
to def subclasses: Seq[() => T]
and def examples(t: () => T)
so that you will create a brand new instance for each example