In specs2 there is no concept of a hierarchical set. A specification is just a list of examples. Even when you group them using xxx should yyy , it just affects how the examples are displayed in the console with more or less indentation.
On the other hand, there are ways to organize specifications with specs2 :
References
You can create a hierarchy of specifications by creating a top-level specification that references others:
// code for specs2 3.x class ParentSpec extends Specification { def is = s2""" These are all the important specifications about our domain ${"child1" ~ ChildSpec1} ${"child2" ~ ChildSpec2} """ }
Baby specifications may refer to other specifications and so on. What sets JUnit apart (and possibly from ScalaTest) is that your link graph does not have to be a tree. When you execute a specification with the argument all
sbt> test-only ParentSpec -- all
then dependencies are executed from ParentSpec , so low-level dependencies are executed before high-level ones. And any loops are broken so that you won't do things endlessly (or get a StackOverflowError ).
Tags
Tags are a very convenient way to classify things, because a given โthingโ should not belong to only one category. This was at that time one of the big improvements caused by TestNG . In specs2, you can mark individual examples or entire specifications and then declare which examples you want to run based on the inclusion / exclusion of some tags. for instance
class Spec1 extends mutable.Specification { section("functional") "simple test" >> ok tag("io") "a bit of IO" >> ok } class Spec2 extends mutable.Specification { section("functional") "another simple test" >> ok tag("io") "another bit of IO" >> ok }
Then you can only execute tags with the functional tag, but not with examples that have the io tag
sbt> test-only -- include functional exclude io
Organization
Using links and tags, you can probably imagine several ways to slice and fix your test source:
- you can use links to create a basic "taxonomy" of specifications.
- you can use tags to create โcross-cuttingโ issues like
io , slow , database , scalacheck ...
Please note that you can also mix all of the above and have tags for your links, specifications with examples and links, etc.
Criteria for choosing this structure:
- navigation around concepts in the code base
- speed of execution of various packages
- the need to restart only certain aspects of your tests after the change
- infrastructure limitations (not everything can work in any environment)