Specs2

Specs2 is a powerful Scala library designed for writing software specifications and tests. It encourages behavior-driven development (BDD) and is well-suited for both unit and acceptance testing. Let's use Specs2 to test the Calculator example, focusing on behavior and readability.

Setting Up

First, ensure Specs2 is included in your build.sbt dependencies:

libraryDependencies ++= Seq(
  "org.specs2" %% "specs2-core" % "4.10.6" % Test,
  "org.specs2" %% "specs2-matcher-extra" % "4.10.6" % Test // For extra matchers
)

Check for the latest version of Specs2 to use in your project.

The Calculator Object

Here's a simple Calculator object to test:

object Calculator:
  def add(a: Int, b: Int): Int = a + b
  def subtract(a: Int, b: Int): Int = a - b
  def multiply(a: Int, b: Int): Int = a * b
  def divide(a: Int, b: Int): Option[Int] = if b == 0 then None else Some(a / b)

Writing Specifications with Specs2

Create a new specification in your src/test/scala directory. Specs2 supports a flexible way to write tests, including the should and must styles. Here, we'll use the should style for clarity:

import org.specs2.mutable.Specification

class CalculatorSpec extends Specification 
  "Calculator" should 
    "correctly add two numbers" in 
      Calculator.add(1, 2) must_== 3
    
    "correctly subtract two numbers" in 
      Calculator.subtract(5, 3) must_== 2
    
    "correctly multiply two numbers" in 
      Calculator.multiply(3, 4) must_== 12
    
    "return None when dividing by zero" in 
      Calculator.divide(5, 0) must beNone

    "correctly divide two numbers" in 
      Calculator.divide(10, 2) must beSome(5)

Running Tests

To run your Specs2 tests, use sbt:

sbt test

This command will compile and execute all test specifications.

Understanding the Specs2 Specification