ScalaTest User Guide

Getting started

Selecting testing styles

Defining base classes

Writing your first test

Using assertions

Tagging your tests

Running your tests

Sharing fixtures

Sharing tests

Using matchers

Testing with mock objects

Property-based testing

Asynchronous testing

Using Scala-js

Using Inside

Using OptionValues

Using EitherValues

Using PartialFunctionValues

Using PrivateMethodTester

Using WrapWith

Philosophy and design

Migrating to 3.0

Tests as specifications

In the behavior-driven development (BDD) style of testing, test suites act as executable specifications—specifications of system behavior that can be executed to verify that behavior. ScalaTest provides rich support for this style of testing.

In BDD, test names are sentences that specify a bit of desired behavior that the body of the test will ensure is working. This keeps tests focused on just one thing, making it easier to figure out what behavior has been broken when a test fails. To keep the focus on specifying behavior, the word “test” disappears from the source code and is replaced with words that make the code feel more like a specification. For example, in ScalaTest's AnyFunSpec trait, you use the word “describe” to name and qualify the subject under test, and “it” to mark the beginning of a sentence about a bit of the subject's behavior. Here's an example AnyFunSpec:

import org.scalatest.funspec.AnyFunSpec
import scala.collection.mutable.Stack

class StackSpec extends AnyFunSpec {
describe("A Stack") {
it("should pop values in last-in-first-out order") { val stack = new Stack[Int] stack.push(1) stack.push(2) assert(stack.pop() === 2) assert(stack.pop() === 1) }
it("should throw NoSuchElementException if an empty stack is popped") { val emptyStack = new Stack[String] intercept[NoSuchElementException] { emptyStack.pop() } } } }

In addition to source code that reads more like a specification, the BDD approach also encourages that test run reports also appear more like specifications. In addition to simply reporting results, specification-style reports can facilitate communication about the system being tested among stakeholders such as developers, managers, and customers. For example, were you to run StackSpec from within the Scala interpreter:

scala> (new StackSpec).execute()

You would see ScalaTest's standard-out reporter display the results as an easy to read as an informal specification of the subject being tested:

A Stack
- should pop values in last-in-first-out order
- should throw NoSuchElementException if an empty stack is popped

ScalaTest also gives you ways to specify with greater granularity than just the test names. For example, mixing in trait GivenWhenThen would enable you to write code like:

import org.scalatest.funspec.AnyFunSpec
import org.scalatest.GivenWhenThen
import scala.collection.mutable.Stack

class StackSpec extends AnyFunSpec with GivenWhenThen {
describe("A Stack") {
it("should pop values in last-in-first-out-order") {
Given("a non-empty stack") val stack = new Stack[Int] stack.push(1) stack.push(2) val oldSize = stack.size
When("pop is invoked on the stack") val result = stack.pop()
Then("the most recently pushed element should be returned") assert(result === 2)
And("the stack should have one less item than before") assert(stack.size === oldSize - 1) }
it("should throw NoSuchElementException if an empty stack is popped") {
Given("an empty stack") val emptyStack = new Stack[String]
When("pop is invoked on the stack") Then("NoSuchElementException should be thrown") intercept[NoSuchElementException] { emptyStack.pop() }
And("the stack should still be empty") assert(emptyStack.isEmpty) } } }

Were you to run this StackSpec in the Scala interpreter, you would see:

A Stack
- should pop values in last-in-first-out-order
  + Given a non-empty stack 
  + When pop is invoked on the stack 
  + Then the most recently pushed element should be returned 
  + And the stack should have one less item than before 
- should throw NoSuchElementException if an empty stack is popped
  + Given an empty stack 
  + When pop is invoked on the stack 
  + Then NoSuchElementException should be thrown 
  + And the stack should still be empty 

ScalaTest provides many traits that facilitate BDD style: Compared to Spec, AnyWordSpec and AnyFlatSpec provide more gramatical structure (e.g., test names must include should, can, or must), whereas AnyFreeSpec gives complete freedom to the writer. Other BDD traits facilitate specific kinds of testing: AnyFeatureSpec's syntax is geared towards acceptance, integration, and functional testing, and AnyPropSpec is geared towards property-based testing.

Next, learn about property-based testing.

ScalaTest is brought to you by Bill Venners and Artima.
ScalaTest is free, open-source software released under the Apache 2.0 license.

If your company loves ScalaTest, please consider sponsoring the project.

Copyright © 2009-2024 Artima, Inc. All Rights Reserved.

artima