Goodbye Cucumber. Hello Spock.

My thoughts on Cucumber Groovy and Spock BDD tools. Since writing this however I actually prefer Cucumber still but am leaving the blog for now. It is what I thought at the time.

Posted: Sat 12 Mar, 2016, 19:29
##BDD

For many years now I have been a massive fan and proponent of BDD - Behaviour Driven Development. In previous roles I have spent time delivering training, prototyping and being embedded in teams trying to adopt it. These days, when I am back at the coal-face doing programming every day, my job is just to write the best code I can. And now I use BDD just for myself and still think it is biggest development game-changer for me personally.

So BDD captures business functionality in specifications that are readable documents. These documents are both your requirements and your evidence that the code works - because they contain examples. Here is an example:

Feature: Calculator feature

        Scenario 1: Ensure can add integers
        Given input for 3
        And input of 2
        When add
        Then ensure result is 5

        Scenario 2: Ensure can subtract integers
        Given input for 3
        And input of 1
        When subtract
        Then ensure result is 2
        

And so forth. The documents are written in special way such that they can be parsed and used to validate functionality. If there is required functionality that is not on the specification, then it is not tested and so you can assume it is not supported. If one wants to find out how the Calculator works, simply read the specification.

I have been using this for many years now and it basically folds the testing into your development in a way that is transparent, automated and gives everyone confidence that a feature works today and will keep on working until changed.

##Concordion and Cucumber

So, thats the basic idea. And there are many tools out there to do the specification parsing and result validation. I have used Concordion and Cucumber JVM. Concordion is great for generating very readable specifications, but has some limitations on re-using steps and it is slow to generate the specifications (need to write HTML). Cucumber JVM is much faster to write specifications, has a very nice tagging feature that lets you invoke any set of tests but it produces very ugly specification output - living documentation it is sometimes called. But this is no big deal to be honest, the power and value is mostly in the specification writing and ease of execution.

##Being Groovy

Recently I have been dabbling with Gradle, Groovy and Spock. And the more I dabble the more I like. Gradle is great but I will save that for another discussion. Groovy is faster to write, more fun to write with less boiler-plating, endless conveniences, closures and some very nice extensions - like GPars for example. It could be the ideal language for writing tests - which need to quick to write. Unlike production code, the test code should generally be simpler, just many small methods and should be written as quickly as possible. So having been a user for Cucumber JVM for a while now, Cucumber Groovy seemed like the obvious choice. Except it wasnt. Cucumber Groovy leverages Mixins in Groovy which render any calling class a "script" which means it is stand-alone entity and cannot benefit from dependency injection (DI). DI is pretty fundamental and I would not wish to try and build complex test fixtures without it. This was somewhat disappointing to say the least.

##Spock

Enter Spock. Spock is a BDD framework written in Groovy. It is quite opinionated and forces code practices that are generally well thought out. For example the test classes must extend Specification, which encourage use of encapsulation rather than inheritance which is generally good practice as far as I am concerned. Plus tests are written in Groovy with annotations that provide full DI support for Spring and Guice. So that problem is solved whilst retaining all the benefits of coding in Groovy. For example GPars - which provides thread-safe concurrent execution of tasks very simply.

My only reservation so far with Spock is that it is a departure from "classic" BDD in that the development process no longer involves writing a specification. The specification document is the human readable definition of what is required. From real-world, pragmatic, practical experience I know that the perfect BDD process whereby this is defined first never happens. So it is actually only the developer who sees the specification, so I am actually not convinced that the supposed benefit of having "living document" is any great loss. To date, I have never seen this being valuable. The real, real value of BDD is by forcing developers to lock in their functionality, take care of quality and be able to "show" that functionality works. This final part of demonstrating functionality works to non-technical people is where Spock still has some work to do - from what I have seen. All that is returned is the high-level test names, not the step or assertion outputs.

Overall, I am prepared to sacrifice this for the overall convenience and speed of coding in Groovy, so I will be continuing to use Spock for now and hope the generation of readable test evidence follows on.