15

I have simple specification with several cases in it:

class MySpec extends Specification {

  "Something" should {

    "case 1" in {
      ...
    }

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

Now I need to start application, run all cases, and shutdown the application. Starting/stopping the application is time consuming and I don't want it to happen around each case.

How do I run code before cases are started and after all the cases have finished?

lambdas
  • 3,990
  • 2
  • 29
  • 54
  • [Scroll down this doc page til Before/After paragraph](http://etorreborre.github.io/specs2/guide/org.specs2.guide.Structure.html) – om-nom-nom Jun 05 '13 at 09:58
  • @om-nom-nom It only explains how to execute code around each case. – lambdas Jun 05 '13 at 10:10
  • whoops, I meant `Template` or `Global setup/teardown` paragraph (the one with database setup/cleanup) :-) – om-nom-nom Jun 05 '13 at 10:14
  • @om-nom-nom I have already. It only explains how to execute code before spec. – lambdas Jun 05 '13 at 10:20
  • I actually had this same situation and did not find any of the out of the box before/after functionality sufficient for my needs. If you can hang in there for about an hour (as I am in transit to work) I will post my solution. – cmbaxter Jun 05 '13 at 10:44
  • @om-nom-nom, broken link :( – Paul Draper Jun 29 '15 at 06:04

4 Answers4

33

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 {
      ...
    }
  }
}
Eric
  • 15,494
  • 38
  • 61
lambdas
  • 3,990
  • 2
  • 29
  • 54
8

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.

cmbaxter
  • 35,283
  • 4
  • 86
  • 95
2

The existing answers are great, but now there is a simple BeforeAfterAll trait in specs2. Overriding it will provide the wanted functionality. For instance, the test:

class ASpec extends Specification with BeforeAfterAll {

  "The 'Hello world' string" should {
    "contain 11 characters" in {
      println("test 1")
      "Hello world" must have size (11)
    }
    "start with 'Hello'" in {
      println("test 2")
      "Hello world" must startWith("Hello")
    }
    "end with 'world'" in {
      println("test 3")
      "Hello world" must endWith("world")
    }
  }

  def beforeAll(): Unit = {
    println("beforeAll")
  }

  def afterAll(): Unit = {
    println("afterAll")
  }
}

Will output:

beforeAll
test 3
test 2
test 1
afterAll
Tomer Shetah
  • 8,413
  • 7
  • 27
  • 35
-1

Ok this is an old question, but it might help someone.

I'm using the Play Framework. In my tests I used org.scalatest.BeforeAndAfterAll

Example:

import org.scalatest.BeforeAndAfterAll

class MySpec extends PlaySpec with BeforeAndAfterAll {

  "Some test" must {
    "print a text" in {

      println("Some test")
      2 mustBe 2
    }
  }

  override def beforeAll(): Unit = {
    println("Before")
  }

  override def afterAll(): Unit = {
    println("After")
  }
}
Agus Arias
  • 467
  • 1
  • 7
  • 5