Sponsored Link •
|
Summary
The latest version of ScalaTest includes a trait named SpecDasher, which when mixed into a Spec facilitates a more concise expression of specification-style tests. It is deprecated, however, and may be removed in a future release depending on user feedback. What's your opinion?
Advertisement
|
The basic form of writing a Spec
in ScalaTest looks a bit like it does in Ruby's RSpec. You name the subject (class or other entity) you are specifying and testing with "describe
" and the actual behavior specifications and accompanying tests (called examples in BDD terminology) with "it
." Here's a simple Spec
:
import org.scalatest.Spec import scala.collection.mutable.Stack class StackSpec extends Spec { describe("A Stack") { it("should pop values in last-in-first-out order") { val stack = new Stack[Int] stack.push(1) stack.push(2) assert(stack.pop() === 2) assert(stack.pop() === 1) } it("should throw NoSuchElementException if an empty stack is popped") { val emptyStack = new Stack[String] intercept[NoSuchElementException] { emptyStack.pop() } } } }
Executing a Spec
will produce specification-style output. For example,
running StackSpec
from within the Scala interpreter, like this:
scala> (new StackSpec).execute()
Will yield:
A Stack - should pop values in last-in-first-out order - should throw NoSuchElementException if an empty stack is popped
With SpecDasher
, you can write the same specification a bit more concisely, like this:
import org.scalatest.Spec import org.scalatest.SpecDasher import scala.collection.mutable.Stack class StackDashSpec extends Spec with SpecDasher { "A Stack" -- { "should pop values in last-in-first-out order" - { val stack = new Stack[Int] stack.push(1) stack.push(2) assert(stack.pop() === 2) assert(stack.pop() === 1) } "should throw NoSuchElementException if an empty stack is popped" - { val emptyStack = new Stack[String] intercept[NoSuchElementException] { emptyStack.pop() } } } }
Running StackDashSpec
will produce the same specification-style output as the previous one:
scala> (new StackDashSpec).execute() A Stack - should pop values in last-in-first-out order - should throw NoSuchElementException if an empty stack is popped
Trait SpecDasher
enables this syntax by offering an implicit conversion from String
to a class named Dasher, which has -
and --
methods. In ScalaTest 0.9.4, trait Spec
already mixes in SpecDasher
, because I showed this syntax in Programming in Scala working just in a plain old Spec
. ScalaTest 0.9.4 is the version that's illustrated in the book, and I wanted all the code in the book to work, but after the book went to the printer I began to have second thoughts about the dashes style. If I do end up leaving SpecDasher
in the API, I will definitely change Spec
so that it doesn't already mix in SpecDasher
. This way users will have to explicitly invite in these implicit conversion by mixing in SpecDasher
explicitly in their own Spec
s.
However, I am also considering simply dropping SpecDasher
entirely, which is why it is deprecated. Although it does clear out just about all clutter around a Spec
, leaving just the specification text and the test code, the difference between a describe
clause (denoted by two dashes) and an it
clause (denoted by one dash) may be less obvious in dashes style. Another advantage that I think explicit "it
" clauses may have is that they may make it more likely people will start the spec text with a verb, usually either "should" or "must".
Also, I didn't provide a way in dashes style to "ignore" a test or place a test into groups, because to do so would have added more syntax to learn for both readers and writers of the tests. If you want to do either of those activities, therefore, you'll need to switch back to the default style. Here's how you'd ignore the first test, and place it in the SlowTests
group:
ignore("should pop values in last-in-first-out order", SlowTests) { val stack = new Stack[Int] stack.push(1) stack.push(2) assert(stack.pop() === 2) assert(stack.pop() === 1) }
Although it is kind of cool to include a class named after one of Santa's reindeer in an API, in general I subscribe to the philosophy that you're not done when you can't think of anything else to add. Rather, you're done when you can't think of anything else to take out. If I do remove SpecDasher
, those that like it could still use it by grabbing the source code (which is very small) and mixing it in locally. But I'd like to hear what others think, because I also subscribe to the philosophy that usually you should try to give the people what they want. Please post your opinion in the discussion forum for this blog post.
Have an opinion? Readers have already posted 1 comment about this weblog entry. Why not add yours?
If you'd like to be notified whenever Bill Venners adds a new entry to his weblog, subscribe to his RSS feed.
Bill Venners is president of Artima, Inc., publisher of Artima Developer (www.artima.com). He is author of the book, Inside the Java Virtual Machine, a programmer-oriented survey of the Java platform's architecture and internals. His popular columns in JavaWorld magazine covered Java internals, object-oriented design, and Jini. Active in the Jini Community since its inception, Bill led the Jini Community's ServiceUI project, whose ServiceUI API became the de facto standard way to associate user interfaces to Jini services. Bill is also the lead developer and designer of ScalaTest, an open source testing tool for Scala and Java developers, and coauthor with Martin Odersky and Lex Spoon of the book, Programming in Scala. |
Sponsored Links
|