In our development, we use TDD, so we have some tests like this:
"User" should {
"return 'Mike' if its name is 'Mike'" in {
val user = User("Mike")
user.getName === "Mike"
}
"return 20 if its age is 20" in {
val user = User(age = Some(20))
user.getAge === Some(20)
}
}
The tests we are writing here looks like "Unit tests".
Then I found specs2 provides another kind of syntax which is more expressible, which I'm interested in:
def is = s2"""
User can have name and age, and we have ways to get them, say, if we have a user whose name is "Mike" and the age is "20",
- we can the name "Mike" [$e1]
- also can get the age 20 [$e2]
"""
def e1 = {
val user = User("Mike")
user.getName === "Mike"
}
def e2 = {
val user = User(age = Some(20))
user.getAge === Some(20)
}
I want to try it with TDD, but soon I found this kind of tests are "Acceptance specification". There is a strong question came into my mind:
What kind of tests are they if we mention "TDD"? Must they be "Unit tests"? Is it good practice to use the "acceptance specification" to drive the implementation?
I want to clarify that in specs2 the terms "Acceptance" and "Unit" refer more about "styles" rather than activities.
I named the "Acceptance specifications" as such because they allow you to express yourself in a style that is common to "acceptance" document which should be easily readable by a non-developer (that is, not cluttered with too much code).
On the other hand the "Unit specifications" are being expressed in a style that is more familiar to people writing unit tests.
But I don't consider this denomination to be prescriptive at all. You are free to choose whatever style you prefer and I frequently use the "Acceptance" style for unit tests!