Scala Problem: You want to make your ScalaTest unit tests more BDD-like by adding “Given/When/Then” behavior to them.
Solution
Mix the GivenWhenThen
trait into your FunSpec
BDD test, then add the Given/When/Then conditions, as shown in the following code:
package com.acme.pizza import org.scalatest.FunSpec import org.scalatest.BeforeAndAfter import org.scalatest.GivenWhenThen class PizzaSpec extends FunSpec with GivenWhenThen { var pizza: Pizza = _ describe("A Pizza") { it ("should allow the addition of toppings") { Given("a new pizza") pizza = new Pizza When("a topping is added") pizza.addTopping(Topping("green olives")) Then("the topping count should be incremented") expectResult(1) { pizza.getToppings.size } And("the topping should be what was added") val t = pizza.getToppings(0) assert(t === new Topping("green olives")) } } }
Assuming that you have the Pizza
and Topping
classes installed as described in Writing TDD Tests with ScalaTest, this class prints the following test output, which provides more detail to anyone reviewing the output:
[info] Compiling 1 Scala source to /Users/Al/Projects/Scala/Tests/ScalaTest1/target/scala-2.10.0/test-classes... [info] PizzaSpec: [info] A Pizza [info] - should allow the addition of toppings [info] + Given a new pizza [info] + When a topping is added [info] + Then the topping count should be incremented [info] + And the topping should be what was added [info] Passed: : Total 2, Failed 0, Errors 0, Passed 2, Skipped 0
Discussion
Where Writing a First BDD Test with ScalaTest got you started down the road of the BDD-style of testing, adding the GivenWhenThen
trait gives you the additional features necessary to more fully implement the BDD style.
Dan North, the creator of the BDD style of testing, describes the Given/When/Then approach on his website. He shows that the basic pattern looks like this:
- Given some initial context (the givens),
- When an event occurs,
- Then ensure some outcomes.
A simple example of this might look like this:
- Given a new pizza
- When a topping is added
- Then the pizza should have one topping
A more complicated example might look like this:
- Given a new pizza
- When new toppings are added
- And the size is set
- And the crust type is set
- Then the pizza should have all of those toppings
- And the crust size should be correct
- And the crust type should be correct
- And the price of the pizza should be X
Adding more tests
As you can see from the output, the Given
method prints “Given” before your string; When
prints “When” before your string; and so on with Then
and And
.
As you add more BDD-style tests to your class:
it("Should start with no toppings") { Given("a new pizza") pizza = new Pizza Then("the topping count should be zero") assert(pizza.getToppings.size == 0) } it("Should allow removal of toppings") { Given("a new pizza with one topping") pizza = new Pizza pizza.addTopping(Topping("green olives")) When("the topping is removed") pizza.removeTopping(Topping("green olives")) Then("the topping count should be zero") expectResult(0) { pizza.getToppings.size } }
you end up with test results that read like a software specification:
[info] Compiling 1 Scala source to /Users/Al/Projects/ScalaTest1/target/scala-2.10.0/test-classes... [info] PizzaSpec: [info] A Pizza [info] - Should start with no toppings [info] + Given a new pizza [info] + Then the topping count should be zero [info] - Should allow the addition of toppings [info] + Given a new pizza [info] + When a topping is added [info] + Then the topping count should be incremented [info] + And the topping should be what was added [info] - Should allow removal of toppings [info] + Given a new pizza with one topping [info] + When the topping is removed [info] + Then the topping count should be zero [info] Passed: : Total 3, Failed 0, Errors 0, Passed 3, Skipped 0
See Also
- A description of Behavior-Driven Development on Wikipedia: http://en.wikipedia.org/wiki/Behavior-driven_development
- Dan North’s original “Introducing BDD” article: http://dannorth.net/introducing-bdd/
- ScalaTest's given/when/then documentation: http://www.scalatest.org/getting_started_with_feature_spec
The Scala Cookbook
This tutorial is sponsored by the Scala Cookbook, which I wrote, and was published by O’Reilly in late 2013:
You can find the Scala Cookbook at these locations:
I hope it has been helpful. All the best, Al.