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")
}
}
}
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)
}