We show how Spock test improves expressivity and readability of tests over JUnit 4. Download a sample setup based on Spock 1.3 on Groovy 2.5 from github.com/JohannesFKnauf/regex-tdd-parameterized-spock-example and start playing.
What are your testing weapons of choice, then?
Colleague: “Java 8, JUnit 4, Maven.”
—Me: “Not exactly my weapons of choice, but well… will do. Let’s get ready to rumble!”
People asked me, what solution I would prefer instead of JUnit 4. To be honest: Pretty much anything. In this post I want to present Spock as a testing toolkit that focuses on expressive language. By the power of Groovy and its Grapes, we also show how to run it as a self-contained script instead of creating a lot of maven boilerplate.
Both aspects – test language and test execution – are separate. In principle, you can also
- run JUnit tests as a self-contained groovy script and
- run Spock using your build tool of choice, e.g. maven or gradle.
Running spock as a self-contained groovy script
For the purpose at hand, setting up a baroque maven project with a lot of boilerplate feels like overkill. We only want to test a simple Regex, after all.
Get the Groovy 2.5 distribution and install it. In doubt, use the default way. Alternative mechanisms you might want to look at are
- your operating system’s native package repository or
- the Groovy docker image from Docker Hub.
After installing we expect you to have a way of calling groovy like this:
parameterized Data Driven Testing in Spock
In order to achieve the same goal as JUnit 4 parameterized tests we use a Spock feature called Data Driven Testing. Let’s go straight to the code:
Did you see it? No XML mumbo-jumbo. Almost no syntactic clutter. Just the tests, the whole tests and nothing but the tests. Lovely, isn’t it?
There are some points, that the anguished experienced developer will highly appreciate:
- Test methods carry free-form string names, noStupidAndHardToReadMixedCaseSentencesWithALotOfFourLetterAcronymsLikeJfgiOrRofl. YouWillLoveIt.
- Test method names contain named (not numbered) template parameters, which correspond to the method parameters.
@Unrollensures that each case is considered a separate test.
- Test sections are separated by natural language labels like
where:(the implementation is powered by the Groovy compiler AST tranformation extensions; LISP-like features with Java-like syntax; Groovy!).
- Test cases are presented in a clearly arranged, easy to read and easy to write ASCII table.
- The regular expression in
/ ... /Groovy syntax does not suffer from the backslash plague, but is otherwise translated to a plain java.util.regex.Pattern when used with the tilde operators like
Running the tests
Well, that does not look so different than before. Under the hood, Spock is driven by JUnit 4 Runner. That is a good thing, as it means you can use Spock in your IDE without any adjustments.
Reaping the benefits of superior failure reports
Just to demonstrate one of the biggest advantages of adopting Spock, we will intentionally break the tests:
Without any debugging, you can exactly see what went wrong. No wonder they are called “Power assertions”.
One Caveat: Spock’s compatility issues
In the end I want to spend a word on the drawbacks: The combination Spock + Groovy sometimes summons the demons from dependency hell. Did you notice the
@GrabExclude boilerplate? This is the remedy to get the script running.
Other advantages of Spock like using Groovy’s dynamic typing for testing Java libraries or even private methods are beyond the scope of this article. But if you like to hear about it, just drop us a line.