Reputation: 16718
In the context of Specs2, a purist may argue that one should use unit testing style to do, well, unit testing. And that Specs2 acceptance testing style is for doing acceptance tests. That sounds kinda obvious ;-)
But, I favour the acceptance testing style of writing even my unit tests (for consistency mostly). Is there any technical reason I should not be doing this?
I just like the consistency of writing all my tests in the same style, and the Unit testing style gets a bit difficult to navigate for my project owners (not so technical people). While the acceptance testing style, allows them to add new tests for missing features as they stumble upon them, e.g:
"Cool new feature" ! todo ^
As you can see from the examples below (adapted from Specs2 site), acceptance testing style is just a bit more readable by non-geeky people and allows a better separation of concerns, especially as the specs gets larger. Also, it may lead to a more compositional style or writing tests.
Unit testing style:
import org.specs2.mutable._
class HelloWorldSpec extends Specification {
"The 'Hello world' string" should {
"contain 11 characters" in {
"Hello world" must have size(11)
}
"start with 'Hello'" in {
"Hello world" must startWith("Hello")
}
"end with 'world'" in {
"Hello world" must endWith("world")
}
}
}
Acceptance testing style:
import org.specs2._
class HelloWorldSpec extends Specification { def is =
"This is a specification to check the 'Hello world' string" ^
p^
"The 'Hello world' string should" ^
"contain 11 characters" ! e1^
"start with 'Hello'" ! e2^
"end with 'world'" ! e3^
"do something cool" ! todo^
"do something cooler" ! todo^
end
def e1 = "Hello world" must have size(11)
def e2 = "Hello world" must startWith("Hello")
def e3 = "Hello world" must endWith("world")
}
Who knows, one day, one may even end with multiple files with an even more readable DSL using string interpolation (or something) and an additional parsing routine:
HelloTest.specs2
s"
This is a specification to check the 'Hello world' string
=========================================================
The 'Hello world' string should
-------------------------------
- $e1 contain 11 characters
- $e2 && $e3 start with 'Hello' and end with 'world'
- $todo do something cool
- $todo do something cooler
"
MyAppSpec2.scala
import org.specs2._
class HelloWorldSpec extends Specification { def is = HelloTest.specs2
def e1 = "Hello world" must have size(11)
def e2 = "Hello world" must startWith("Hello")
def e3 = "Hello world" must endWith("world")
}
Upvotes: 3
Views: 769
Reputation: 15557
There is no technical reason why you can't use the "Acceptance" style for writing unit tests and conversely use the "Unit" style for writing acceptance tests (because you can use an editor with code folding to show the text only, or you can execute the specification with the plan
argument and get the full text of the specification without executing the examples).
Two "technical" things you need to be aware though:
a "unit" specification uses a variable to register examples so it is subject to concurrency issues if, by any chance, you'd try to build such a specification with different threads
an "acceptance" specification uses the last value of an example as it's result. So, by default, it's less convenient when you want to write one expectation per line in an example. To work around this, you need to mix-in the ThrownExpectation
trait or to use the and
operator between expectations
Finally, I will certainly investigate the possibility to use string interpolation for acceptance specifications when Scala 2.10 is out.
Upvotes: 3