Specify your software using both text and Scala code
class HelloWorldSpec extends Specification { def is = s2"""

  This is a specification for the 'Hello world' string

  The 'Hello world' string should
    contain 11 characters                             $e1
    start with 'Hello'                                $e2
    end with 'world'                                  $e3
                                                      """
  def e1 = "Hello world" must haveSize(11)
  def e2 = "Hello world" must startWith("Hello")
  def e3 = "Hello world" must endWith("world")

}
Use different styles of specifications
/** This is the "Unit" style for specifications */
class HelloWorldSpec extends Specification {
  "This is a specification for the 'Hello world' string".txt

  "The 'Hello world' string should" >> {
    "contain 11 characters" >> {
      "Hello world" must haveSize(11)
    }
    "start with 'Hello'" >> {
      "Hello world" must startWith("Hello")
    }
    "end with 'world'" >> {
      "Hello world" must endWith("world")
    }
  }
}
Test your code with ScalaCheck
class IntSumSpec extends Specification with ScalaCheck { def is = s2"""

  The IntSum Monoid must respect Monoid laws
    left identity                                     $leftid
    right identity                                    $rightid
    associativity                                     $associativity
                                                      """
  import scalaz._, Scalaz._
  import IntSumMonoid._

  def leftid  = prop { i: Int => 0 |+| i === i }
  def rightid = prop { i: Int => i |+| 0 === i }

  def associativity = prop { (a: Int, b: Int, c: Int) =>
    ((a |+| b) |+| c) === (a |+| (b |+| c))
  }

}
Document your APIs with compiler-checked examples
class PluralSpec extends Specification { def is = s2"""

  Names can be pluralized depending on a quantity
  ${ "apple".plural(1) === "apple"  }
  ${ "apple".plural(2) === "apples" }
  ${ "foot".plural(2)  === "feet"   }

  ${ 1.qty("apple") === "1 apple"  }
  ${ 2.qty("apple") === "2 apples" }
  ${ 2.qty("foot")  === "2 feet"   }
  """
}
Manage contexts for integration testing
class UsersSpec extends Specification with BeforeAll with Before {
  def is = sequential ^ s2"""

  We can create in the database
    create a user                                    $create
    list all users                                   $list
                                                     """
  import DB._

  def create = {
    val id = db.createUser("me")
    db.getUser(id).name must_== "me"
  }

  def list = {
    List("me", "you").foreach(db.createUser)
    db.listAllUsers.map(_.name).toSet must_== Set("me", "you")
  }

  // create a database before running anything
  def beforeAll = createDatabase(databaseUrl)
  // remove all data before running an example
  def before = cleanDatabase(databaseUrl)

}
Previous Next