Problem: You want to write your ScalaTest tests using a behavior-driven development (BDD) style.
Solution
Extend the ScalaTest FunSpec
trait, typically with the BeforeAndAfter
trait. Then use the approach shown in the following PizzaSpec
test class.
A series of tests begins with the describe
method, with individual tests declared in it
methods:
package com.acme.pizza import org.scalatest.FunSpec import org.scalatest.BeforeAndAfter class PizzaSpec extends FunSpec with BeforeAndAfter { var pizza: Pizza = _ before { pizza = new Pizza } describe("A Pizza") { it("should start with no toppings") { assert(pizza.getToppings.size == 0) } it("should allow addition of toppings") (pending) it("should allow removal of toppings") (pending) } }
Notice how before
, describe
, and it
seem more like operators than methods. Scala gives developers the power to create their own domain specific languages (DSLs) like this.
Note: Use it
in the singular context, and they
when referring to a plural context. The methods are interchangeable, and intended to make your code more readable.
This class should be placed in a file named PizzaSpec.scala, in a directory named src/test/scala/com/acme/pizza, under your root SBT folder. Assuming that you also have the Pizza
and Topping
classes installed as described in ScalaTest 102: Writing TDD tests with ScalaTest, you’ll see the following output when you run the tests with sbt test
:
[info] PizzaSpec: [info] A Pizza [info] - should start with no toppings [info] - should allow addition of toppings (pending) [info] - should allow removal of toppings (pending) [info] Passed: : Total 1, Failed 0, Errors 0, Passed 1, Skipped 2
Discussion
As you can see, the output of a set of BDD-style tests reads like a software specification: “A Pizza should ...”, followed by a series of statements about what the Pizza
class should do. You’ll see how this gets even better in subsequent recipes.
To see what the output looks like when it fails, if you intentionally inject an error into your first test, setting the size to 1 (instead of 0), the sbt test
output will look like this instead:
[info] PizzaSpec: [info] A Pizza [info] - should start with no toppings *** FAILED *** [info] org.scalatest.exceptions.TestFailedException was thrown. (PizzaSpec.scala:17) [info] - should allow addition of toppings (pending) [info] - should allow removal of toppings (pending) [error] Failed: : Total 3, Failed 1, Errors 0, Passed 0, Skipped 2 [error] Failed tests: [error] com.acme.pizza.PizzaSpec [error] {file:/Users/Al/Tests/ScalaTest1/}default-d6b943/test:test: Tests unsuccessful
this post is sponsored by my books: | |||
#1 New Release |
FP Best Seller |
Learn Scala 3 |
Learn FP Fast |