Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

FlatSpec

Using FlatSpec in ScalaTest allows for behavior-driven development (BDD) style testing, which is very expressive and helps in writing readable tests. Let's apply FlatSpec to test the Calculator example, focusing on behavior descriptions and testing scenarios.

Step 1: Implement the Calculator

First, define a simple Calculator object with basic arithmetic operations:

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): Either[String, Int] =
    if (b == 0) Left("Division by zero")
    else Right(a / b)
}

Notice the divide method returns an Either[String, Int] to handle division by zero gracefully.

Step 2: Set Up ScalaTest Dependency

Ensure ScalaTest is added to your build.sbt:

libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.9" % Test

Step 3: Write Tests Using FlatSpec

Create a test class for Calculator using FlatSpec. This style allows you to specify the behavior of an operation and then describe tests that confirm the behavior.

import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers

class CalculatorSpec extends AnyFlatSpec with Matchers {

  "The Calculator add method" should "return the sum of two numbers" in {
    Calculator.add(1, 2) should be (3)
  }

  it should "return the correct sum when adding negative numbers" in {
    Calculator.add(-1, -2) should be (-3)
  }

  "The Calculator subtract method" should "return the difference of two numbers" in {
    Calculator.subtract(5, 3) should be (2)
  }

  "The Calculator multiply method" should "return the product of two numbers" in {
    Calculator.multiply(5, 4) should be (20)
  }

  "The Calculator divide method" should "return the quotient of two numbers" in {
    Calculator.divide(10, 2) should be (Right(5))
  }

  it should "return an error for division by zero" in {
    Calculator.divide(5, 0) should be (Left("Division by zero"))
  }
}

Step 4: Running Tests

To run your tests, use the sbt command line tool in your project root:

sbt test

This will compile and execute all test suites in your project, including the CalculatorSpec.

Understanding the Test Code

  • AnyFlatSpec with Matchers: This combination allows for a BDD style testing. Matchers provide a readable way to assert conditions.
  • Behavior Descriptions: Using should and strings, you can describe the behavior you're testing. It's a natural language-like approach that makes tests easier to read and understand.
  • Tests for Each Behavior: Under each behavior description, use it should to specify different scenarios or conditions you're testing for that behavior.