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 IntMonoidSpec extends Specification with ScalaCheck:
def is = s2"""
The Int Monoid must respect the Monoid laws
left identity $leftIdentity
right identity $rightIdentity
associativity $associativity
"""
import cats.*, implicits.*
def leftIdentity = prop { i: Int =>
0 |+| i === i
}
def rightIdentity = 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 BeforeSpec with BeforeEach:
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 === "me"
def list =
List("me", "you").foreach(db.createUser)
db.listAllUsers.map(_.name).toSet === Set("me", "you")
// create a database before running anything
def beforeSpec = createDatabase(databaseUrl)
// remove all data before running an example
def before = cleanDatabase(databaseUrl)