How to make working with specs2 much easier

How to make working with Specs2 much easier

How to make working with specs2 much easier

Hi. Specs2 is one of the most popular Scala libraries for testing, but definitely not a simple one. That’s why I’ve decided to create a blog post with a few tricks on how to make working with Specs2 much easier. The examples are 100% artificial, but their purpose is only to demonstrate the capabilities of Specs2.

Basic example

Ok, so let’s start with a basic example.

import org.specs2.mutable.Specification

class MathSpec extends Specification {
  "Math" should {
    "add" in {
      1+2 === 3
    }
  }
}

Pass the data into the tests

We can do this in (at least) two ways. Just pass the data as regular variables:

import org.specs2.mutable.Specification

class MathSpec extends Specification {
  "Math" should {
    val pi = 3.14
    "multiply" in {
      2*pi === 6.28
    }
  }
}

or pass them as a scope

import org.specs2.mutable.Specification
import org.specs2.specification.Scope

class MathSpec extends Specification {

  class Context extends Scope {
    val pi = 3.14
  }

  "Math" should {
    "multiply" in new Context {
      2*pi === 6.28
    }
  }
}

The first option is very straightforward and works well for small tests, but is impractical for bigger ones or when you want to (for some reason) share the values.

Implement custom Setup and Teardown

Now let’s say that we need to perform some important operations before and after every single test case. How can we achieve that? It’s simple. We can use Contexts again.

First of all, we need to create a helper for the local setup and Teardown. We can do it like this:

trait Context extends BeforeAfter {
  def before: Any = println("Doing setup")
  def after: Any = println("Done. Cleanup")
}

now we can do

Implement custom Setup and Teardown for all test cases

The above example works well, but only for single test cases. So now let’s write something for the whole test suite.

import org.specs2.mutable.Specification
import org.specs2.specification.{Step, Fragments}

trait BeforeAllAfterAll extends Specification {
  override def map(fragments: => Fragments) =
    Step(beforeAll) ^ fragments ^ Step(afterAll)

  protected def beforeAll()
  protected def afterAll()
}

class MathSpec extends Specification with BeforeAllAfterAll {

  def beforeAll() {
    println("Starting MathSpec")
  }

  def afterAll() {
    println("Ending MathSpec")
  }

  "Math" should {
    "divide" in {
      8/2 === 4
    }
  }
}

Random thoughts

  1. Watch out for the static configuration and methods, they might cause tests to break from time to time.
  2. When using Specs2, try not to mix sub-packages. Some mixins from org.specs2.mutable might not work with those from org.specs2.specification and so on. Even worse, they might just fail silently.
  3. As you have probably already noticed, Contexts can be classes, traits, and objects.

Do you like this post? Want to stay updated? Follow us on Twitter.

Read also:

Download e-book:

Scalac Case Study Book

Download now

Authors

Patryk Jażdżewski

I'm a software consultant always looking for a problem to solve. Although I focus on Scala and related technologies at the moment, during the last few years I also got my hands dirty working on Android and JavaScript apps. My goal is to solve a problem and learn something from it. While working with teams I follow "The Boy Scout" Rule - "Always check a module in a cleaner state than when you checked it out". I think this rule is so good, that I extend it also to other aspects of software development - I try to improve communication patterns, processes and practices ... and all the things that might seem non-technical but are vital to success.

Latest Blogposts

08.05.2024 / By  Scalac Team

Figma to React: Design to Code Conversion

From Figma to React

From Figma to React: Introduction Recently, within our team, a discussion emerged about converting designs made in Figma into React code. This conversation was sparked due to the constant evolution of tools available for developers. While the possibility of converting design to code has existed for some time, its implementation has been, frankly speaking, suboptimal. […]

29.04.2024 / By  Matylda Kamińska

Scalendar May 2024

scalendar may 2024

Event-driven Newsletter Welcome to our May 2024 edition of Scalendar! As we move into a bustling spring, this issue brings you a compilation of the most anticipated frontend and software architecture events around the globe. With a particular focus on Scala conferences in May 2024, our newsletter serves as your guide to keep you updated […]

23.04.2024 / By  Bartosz Budnik

Kalix tutorial: Building invoice application

Kalix app building.

Scala is well-known for its great functional scala libraries which enable the building of complex applications designed for streaming data or providing reliable solutions with effect systems. However, there are not that many solutions which we could call frameworks to provide every necessary tool and out-of-the box integrations with databases, message brokers, etc. In 2022, Kalix was […]

software product development

Need a successful project?

Estimate project