Selection

Many specifications are written incrementally. You specify a little bit then you implement the application. When you go through this “Specify-Implement-Execute” cycle it is useful to be able to focus on just one example, the one you are currently working on. The ex argument is what you need (ex stands for “example”):

sbt> testOnly *MySpecification* -- ex contains

The command above will execute any example which description matches the regular expression .*contains.* (which means that you can pass regular expressions in general). If you want to match a few words you will need to use double quotes:

sbt> testOnly *MySpecification* -- ex "contains hello" sequential

Use tags

Tags can be used in a Specification to include or exclude some examples or a complete section of fragments from the execution. Let’s have a look at one example:

class TaggedSpecification extends Specification { def is = s2"""
 this is some introductory text
  and the first group of examples
  example 1 $success                         ${tag("feature1", "unit")}
  example 2 $success                         ${tag("integration")}

  and the second group of examples           ${section("checkin")}
  example 3 $success
  example 4 $success                         ${section("checkin")}
                                             """
  }

In that specification we are defining several tags and sections:

Armed with this, it is now easy to include or exclude portions of the specification at execution time:

In a unit specification

A unit specification will accept the same tag and section methods but the behavior will be slightly different:

import org.specs2.mutable._

class TaggedSpecification extends Specification {
  "this is some introductory text" >> {
    "and the first group of examples" >> {
      tag("feature 1", "unit")
      "example 1" in success
      "example 2" in success
    }
  }
  section("checkin")
  "and the second group of examples" >> {
    "example 3" in success
    "example 4" in success
  }
  section("checkin")

  "and the last group of examples" >> {
    "example 5" in success tag "integration"
    "example 6" in success
  } section "slow"
}

For that specification above, tags can be applied to fragments following them:

But they can also be applied to fragments preceding them:

Automatic sections

If you call addSections from inside the specification, each “block” will be surrounded by section tags having the same name as the block text:

import org.specs2.mutable._

class SectionsSpecification extends Specification { addSections
  "first section" >> {
    "and the first group of examples" >> {
      "example 1" in success
      "example 2" in success
    }
  }
  "second section" >> {
    "example 3" in success
    "example 4" in success
  }

  "third section" >> {
    "example 5" in success
    "example 6" in success
  }
}

If you want you can execute only example 3 and 4 by running sbt> testOnly *SectionsSpecification -- include "second section".

Always tag

Some specifications need to have Steps which will always be included whatever tags are specified on the command line. This is the case when defining a “template” specification with setup/teardown steps:

trait DatabaseSpec extends Specification {
  override def map(fs: =>Fragments) =
    step("startDb") ^ tag(AlwaysTag) ^
    fs ^
    step("cleanDb") ^ tag(AlwaysTag)
}

Select failed examples

Another frequent mode of selection is the selection based on previous execution. Generally we want to re-execute only what was broken before. For this, using the was argument on the command-line:

sbt> testOnly *MyFailedSpecification* -- was x

On the line above x is the status of the previous example. Here is a table of all the flags you can use:

Flag Description
+ successful example
x failed example
! error example
o skipped example
* pending example
- text
1 statistics

This selection works because specs2 stores the state of each specification in a directory after a run (target/specs2-reports/stats by default). If you decide that this storing is useless and you want to skip it you can use the neverstore argument. Otherwise if you want to make sure that the stats directory doesn’t become too big over time you can use the resetstore argument which will remove the current store before running the specification.

And if you want to know more