Execute code before and after specification

Okay, as mentioned in my comment, I actually had this same issue. I needed to test Unfiltered endpoints, and the best way for each spec was to startup an Unfiltered server with a single endpoint, run the spec and then shutdown the server. To accomplish that, I first defined a base specification similar to this:

import org.specs2.mutable.Specification

abstract class SpecificationBase extends Specification{
  //Do setup work here
  step{
    println("Doing setup work...")
    success
  }

  //Include the real spec from the derived class
  include(spec)

  //Do shutdown work here
  step{
    println("Doing shutdown work...")
    success
  }  

  /**
   * To be implemented in the derived class.  Returns the real specification
   * @return Specification
   */
  def spec:Specification
}

Basically, this base class assembles the complete specification as a setup step and a teardown step with the real specification (defined in the concrete spec class) sandwiched in the middle. So a test using this base class would look like this:

class MySpec extends SpecificationBase{ def spec = 
  new Specification{
    "A request to do something" should{
      "be successful in case 1" in {
        println("Testing case 1")
        success
      }
      "be successful in case 2" in {
        println("Testing case 2")
        success
      }      
    }
  }
}

When you run this, you will see:

Doing setup work...
Testing case 1
Testing case 2
Doing shutdown work...

It's not perfect, but it works. Is there another (and possible cleaner/better) way to do this? Probably, but this is one solution you could look into using.


I've come up with the following solution based on cmbaxter answer.

import org.specs2.specification.Step

trait BeforeAllAfterAll extends Specification {
  // see http://bit.ly/11I9kFM (specs2 User Guide)
  override def map(fragments: =>Fragments) = 
    Step(beforeAll) ^ fragments ^ Step(afterAll)

  protected def beforeAll()
  protected def afterAll()
}

Then mix BeforeAllAfterAll in Specification and implement beforeAll and afterAll methods:

class MySpec extends Specification with BeforeAllAfterAll {

  def beforeAll() {
    println("Doing setup work...")
  }

  def afterAll() {
    println("Doing shutdown work...")
  }

  "Something" should {

    "case 1" in {
      ...
    }

    "case 2" in {
      ...
    }
  }
}

Finally, extract initialization to share it between specifications:

trait InApplication extends BeforeAllAfterAll {
  def beforeAll() {
    println("Doing setup work...")
  }

  def afterAll() {
    println("Doing shutdown work...")
  }
}

class MySpec extends Specification with InApplication {

  "Something" should {

    "case 1" in {
      ...
    }

    "case 2" in {
      ...
    }
  }
}