Recommended: Sing it, brah! 5 fabulous songs for developers
JW's Top 5
Because it’s my bag, I’ve recently taken to learning Scala. In particular, I’ve run across some situations where I’ve known instinctively that a more functional language (i.e. one that avoids state and mutability) would have perhaps made the task at hand a bit easier or at least safer to code (think situations involving threads (i.e. concurrency), for instance). And while I’ve thus far handled those situations with various libraries and frameworks on the JVM (either straight Java or via Groovy), Scala has always held my interest in that the language is functional by nature — that is, functional aspects are intrinsically present as opposed to added in or forced via additional libraries, etc.
One of my favorite techniques for learning a new language is to leverage it via a testing framework — that way, you get to learn the syntax while also learning about how the language behaves. For instance, because BDD is my bag, I thought I’d start things off by writing a few behaviors with ScalaTest. Briefly, ScalaTest is
an open source test framework [written in Scala] for the Java platform designed to increase your productivity by letting you write fewer lines of test code that more clearly reveal your intent.
Interestingly, they team behind ScalaTest has even trademarked the slogan
Less code, more clarity
Of course, I’m all about less code and more clarity — I’m all about easy, baby! So I thought it would be fun while learning about Scala to also compare and contrast Scala and ScalaTest to Groovy and easyb. Before I go any further, please allow me to state, for the record, that I’m much for familiar with Groovy than Scala and that I’m almost certainly biased towards easyb no matter how hard I might try to admit otherwise. Nevertheless, I do believe I can be objective in this situation as I am intent on leveraging Scala where appropriate.
The ScalaTest team has done a wonderful job of documenting the various options available for testing; in fact, they’ve got an entire section dedicated to BDD-style testing; in particular, they have an RSpec inspired syntax that is obviously similar to easyb’s specification syntax (which was also inspired by RSpec). Thus, with ScalaTest’s Spec trait, you can leverage an it-style syntax for behavior verification; plus, via Scala’s mix-ins feature, you can also leverage a more natural should-style of verification, which definitely leads to a more readable specification.
Using the ScalaTest documentation, you can create a specification that describes a stack like so:
import org.scalatest.Spec
class ExampleSpec extends Spec {
describe("A Stack") {
it("should pop values in last-in-first-out order") (pending)
it("should throw NoSuchElementException if an empty stack is popped") (pending)
}
}
This is, of course, runnable and yields a report that states that there are two pending tests (or behaviors). Note, with ScalaTest, you must indicate a specification is pending by appending a (pending) clause.
Conversely, with easyb, the same specification can be written like so:
description "this specification describes a stack"
it "should pop values in last-in-first-out order"
it "should throw NoSuchElementException if an empty stack is popped"
What’s noticeably lacking from easyb’s syntax is the describe clause (which, in many ways, is just like a scenario); however, easyb doesn’t force you do declare that a particular behavior is pending — it’ll figure that out by itself. What’s more, you aren’t forced to create a class structure to contain your specification. You don’t have to import anything either.
Next, when you decide to code your behavior, in ScalaTest, you implement the it’s method body like so:
import org.scalatest.Spec
import org.scalatest.matchers.ShouldMatchers
import scala.collection.mutable.Stack
class ExampleSpec extends Spec with ShouldMatchers {
describe("A Stack") {
it("should pop values in last-in-first-out order") {
val stack = new Stack[Int]
stack.push(1)
stack.push(2)
stack.pop() should be === 2
stack.pop() should be === 1
}
it("should throw NoSuchElementException if an empty stack is popped") {
val emptyStack = new Stack[String]
evaluating { emptyStack.pop() } should produce [NoSuchElementException]
}
}
}
As you can see from the code above, this behavior is validating a simple Stack object– in this case, its Scala’s own stack implementation; suffice to say, it behaves, for the most part, just like a normal stack. First and foremost, ScalaTest’s ShouldMatchers mixin is slick! Note how you can literally write should be and then pass in a condition. I think this syntax reads nicely (except for the fact that ScalaTest is using 3 =’s). Moreover, exception verification is quite nice too — the evaluating line is quite elegant and the keyword produce is hip! I take it the produce clause takes a collection of exceptions, so it would be nice if, in the case of only one exception, you could drop the [] syntax though.
ScalaTest also has another mixin type dubbed MustMatchers, which replaces should with must should you want to use that word instead.
The same verification process in easyb looks like so (note, in the code below, I’m going to use Java’s Stack):
description "this specification describes a stack"
it "should pop values in last-in-first-out order", {
stack = new Stack<Integer>()
stack.push 1
stack.push 2
stack.pop().shouldBe 2
stack.pop().shouldBe 1
}
it "should throw EmptyStackException if an empty stack is popped", {
emptyStack = new Stack<String>()
ensureThrows(EmptyStackException){
emptyStack.pop()
}
}
In easyb’s case, the actual assertion-like clause is shouldBe (or its cousins like shouldEqual, etc); what’s more, you must “attach” the clause to the desired object (as opposed to ScalaTest’s more removed syntax, which allows you to drop .’s). Nevertheless, the shouldBe call doesn’t insert an additional operator either (i.e. there isn’t the ===). easyb’s exception verification is certainly not as nice as ScalaTest’s though — I suppose I could write the ensureThrows clause as one line but it doesn’t read as nicely as evaluating { blah } should produce [Exception] — I really like that syntax in ScalaTest.
As you can see from these two simple examples, the spirit of BDD is there — each framework takes a slightly different approach in terms of syntax, but that’s probably due to the underlying nature of the languages themselves. Scala is certainly less verbose than normal Java, but it seems to me that Groovy is less verbose than Scala (but I concede that this might just be a result of each framework’s syntax) . I find that easyb yields more clarity but I do find that ScalaTest’s matchers syntax to read quite nicely.
Scala is definitely an interesting language that exposes some interesting features. Like every other major player on the JVM, it has its spot — for me, the strict nature of its typing and functional-ness makes it applicable in concurrency situations; however, its syntax, while less verbose than that of Java, isn’t necessarily as flexible as Groovy, for instance (although dropping the dot (“.”) on method calls makes successive method calls read copasetically (i.e. should be)).
ScalaTest is well documented and offers quite a few neat options (via Scala traits & mixins) that make testing a lot more interesting and certainly clearer than plain Jane JUnits; however, for me, I still find easyb’s syntax to be much more clarifying (and of course, much less code). Nevertheless, for Scala code that I do write, I’ll be leveraging ScalaTest — it’s already taught me a few things! Can you dig it, man?
Looking to spin up Continuous Integration quickly? Check out www.ciinabox.com.