Welcome to Spock: Up and Running. I’m excited and privileged to be your guide as you learn about the most innovative thing to happen to testing on the Java Virtual Machine (JVM) since the first release of JUnit.
From the time I first began writing unit tests (badly), I’ve always been interested in making my tests as well-structured, readable, and straightforward as possible. I embraced the move from JUnit 3 to JUnit 4 with Hamcrest and have experimented with everything from FitNesse to Cucumber, TestNG to Jasmine, and ScalaTest to Spek. I don’t think anything has made the impact on my testing style that Spock has.
For me, Spock is absolutely the “killer app” of the Groovy ecosystem. Sure, GPars made concurrency easy, Gradle saved builds from XML hell, and Grails made throwing together the basics of a web app the work of minutes rather than hours. But nothing exploits Groovy’s dynamic style to build something that genuinely makes things easier and better as successfully as Spock.
And Spock makes things better not just for the 80 percent of cases, but across the board. I have every respect in the world for JUnit—it’s without doubt one of the most important innovations in the history of the JVM—but I can’t think of any case I can tackle better with JUnit than I can with Spock.
I hope you find Spock as logical, fascinating, and useful as I do.
Spock is a test framework—some would even say language—built on top of Groovy. It was developed by Peter Niederwieser, first released in 2009, and, after a long genesis, version 1.0 was released in 2015. Version 1.1 followed in 2017, and that’s the version we’ll be using in this book.
Although Spock builds on top of JUnit’s test runner it’s quite different syntactically.
Spock enforces a behavior-driven development (BDD)-style structure.
Instead of using methods to apply assertions, Spock infers that simple Boolean expressions in particular contexts behave as assertions.
Instead of integrating external libraries like JMock or Mockito, Spock has its own test doubles with dedicated syntax for defining expectations and behavior (although you can use something else if you want).
Spock also has syntax for defining parameterized tests that goes far beyond the capabilities of JUnit’s
Above all, Spock specifications are very readable and expressive. Groovy’s brevity and lack of ceremony is harnessed to a syntax that makes tests read very well as executable documentation.
Groovy is a dynamic, optionally typed language for the JVM that was released in 2007; as of this writing, it is currently up to version 2.4.7. Unlike some alternate JVM languages, Groovy uses very Java-like syntax. In fact, until the release of Java 8, almost all Java code was also valid Groovy code (only one obscure loop formation wasn’t supported). However, Groovy adds the ability to optionally type declarations, and supports duck typing, higher-order functions, metaprogramming capabilities, runtime method dispatch, and a number of other features.
Originally envisaged as a scripting language for the JVM, Groovy grew beyond that into a full-fledged alternate language with its own ecosystem of libraries, web frameworks, and so on. In 2012, Groovy added optional static compilation capabilities and can now target the Android platform.
Groovy’s profile was boosted by two major developments: Grails, a Rails-like web framework that used Groovy code on top of an opinionated Spring and Hibernate stack; and Gradle, a build tool that combined the opinionated declarative style of Maven with the scripting capabilities of Make. When Google made Gradle the official build tool for the Android platform, an entire new community of developers was suddenly exposed to the Groovy ecosystem.
Spock is built on top of Groovy, and Spock specifications are implemented as .groovy files. However, Spock specifications aren’t just JUnit tests written in Groovy. There’s a whole lot more to Spock than that.
Syntax that would make no sense in Groovy might be valid in Spock. Spock is a domain-specific language (DSL) in the truest sense that happens to be built on top of Groovy.
I’ve deliberately avoided as much advanced Groovy as possible in the examples. We’re not here to do incredible things with metaprogramming or to debate whether that’s a good idea. The Groovy code used in the example specifications is, wherever possible, simple, concise, idiomatic, and unsurprising.
In the past decade, automated testing has gone from a frequently derided fringe practice to the mainstream. Resistance is futile. I think it’s fair to say that the majority of developers at least acknowledge the benefits of writing tests, even if they only pay lip service to the discipline of testing their own software.
But to many developers, testing is a tough discipline to master. It feels to many people like it shouldn’t be something that they should dedicate a lot of time to, but writing tests is unlike writing production software. It’s an orthogonal, albeit related, skill. Beyond just the tests themselves, designing software that is amenable to testing often requires a shift in approach that can be difficult to overcome.
Hopefully, coming to this book, you are at least convinced that automated testing sounds like a good idea.
If you’d like to begin writing tests, and Spock looks like an interesting tool for doing so, this book is for you.
If you have tried writing tests and found it difficult to grasp how to proceed, this book is for you.
If you write tests but find it difficult to test some aspects of your code, this book is for you.
If you just want to write tests that are less prone to breaking as the system changes, this book is for you.
You don’t need to be a Groovy developer—in fact, this book assumes that you have no knowledge of the Groovy language. There’s a Groovy primer in Appendix A should you need it. All the nontest code used in the examples in this book is written in Java.
The point is, you don’t need to be a Groovy expert to get the best out of this book. In fact, you don’t even need to have any intention of ever writing production code in Groovy. One of the things I’m keenest to convey here is that Spock is great for testing Java code.
If you do know some Groovy, great. You can skip the appendix!
My first unit test was written for a coding exercise given to me as part of an interview with ThoughtWorks (I didn’t get the job). I’m sure it was pretty terrible. I wrote a single test method for each public API method in the class under test. I tested multiple aspects of the behavior in each test method and missed numerous edge cases. I wasn’t focused on behavior or using the tests to guide the design of the code so that it was easier to understand or write more tests for.
I’d have loved a book on the practice of writing tests. But it was the early 2000s. JUnit was pretty new. Test-driven development (TDD) was a radical practice considered ridiculously utopian by most “serious” developers. The material that was available was mostly focused on the details of JUnit or a high-level view of the TDD approach. There wasn’t much out there that would just help me write better tests.
These days, that’s no longer the case. I hope this book is a good addition to the library of excellent material available to today’s software developer.
Developers today are spoiled for choice. Every language I can think of has one or more frameworks for composing and running automated tests.
But writing good, well-structured tests is still an elusive skill. Writing tests that clearly separate dummy data from test logic is tricky. Learning to use mocks and stubs appropriately is a mountain to climb—so much so that some will tell you mocks and stubs are a bad thing altogether. Certainly, when used badly, they result in tests that are difficult to read and more difficult still to maintain. Used well, they are powerful tools for designing and testing for a “separation of concerns.”
In this book, I don’t want to just show you how to use Spock. I want to show you how to use it well; how to write tests that don’t require constant maintenance as the project progresses; how to write tests that communicate to the reader what the behavior of the system and its components is; and how to write tests that help you identify problems when they fail rather than feeling like just another meaningless bit of bureaucracy you have to get past on the way to deploying your code.
It’s even possible to test drive a book now.
The examples in this book are all working code. The entire book is a Gradle project; the code listings are included from actual specifications that execute as the book “builds.”
Hopefully that means there are minimal errors!
Through the course of this book, we’ll build up a simple web application—Squawker—that allows users to post short messages. Squawker users can follow one another, mention one another in messages, view a timeline of messages from the users they follow, or just squawk out into the void!
Hopefully, this concept sounds pretty familiar; that’s certainly the idea. I’d rather you were able to attach the testing concepts in the book to a recognizable, practical idea than have to spend several chapters describing what the application does in exhaustive detail.
Some chapters will divert from the Squawker example where it makes more sense. I’d rather switch to a standalone example than try to bash the square peg of Squawker into the round hole of the topic at hand.
The book is organized into three parts. In Part I, we dive into Spock 101, learning the basics of Spock, its syntax, and everything you need to get from zero to writing simple unit tests.
Chapter 2 and Chapter 3 discuss how to structure specifications and how to write assertions. Chapter 4 discusses the lifecycle of Spock specifications and feature methods. Chapter 5 introduces interaction testing with mocks and stubs, and the intuitive syntax Spock employs for dealing with them. Chapter 6 deals with parameterized tests—writing feature methods that run for multiple sets of data.
Part II takes you beyond the basics into some advanced topics such as how to write idiomatic Spock code (Chapter 7), driving parameterized tests with file or database input (Chapter 8), and Spock’s support for asynchronous testing (Chapter 9). We’ll also look in Chapter 10 at how to extend Spock using JUnit rules and other test libraries and how to write custom Spock extensions. Finally we’ll bring everything together in Chapter 11 with a standalone fully worked TDD example.
At the back of the book is a Groovy primer, Appendix A. One of things I’m keen to get across in this book is that Spock is not just for testing applications written in Groovy. I use Spock for testing Java applications every day. Although this book assumes you are familiar with Java, no knowledge of Groovy is necessary. All the application code in the examples is written in Java. Groovy is used only for Spock specifications.
If you’re completely unfamiliar with Groovy it might be wise to skip ahead to the Groovy primer and start there. If you’re somewhat familiar with Groovy, it should serve as a good memory aid or reference. If you’re all up to speed on Groovy, great, feel free to skip the primer altogether.
Indicates new terms, URLs, email addresses, filenames, and file extensions.
Used for program listings, as well as within paragraphs to refer to program elements such as variable or function names, databases, data types, environment variables, statements, and keywords.
Constant width bold
Shows commands or other text that should be typed literally by the user.
Constant width italic
Shows text that should be replaced with user-supplied values or by values determined by context.
This icon signifies additional information beyond the example at hand.
This icon signifies a tip, suggestion, or general note.
This icon indicates a warning or caution.
Supplemental material (code examples, exercises, etc.) is available for download at https://github.com/robfletcher/spock-up-and-running.
This book is here to help you get your job done. In general, if example code is offered with this book, you may use it in your programs and documentation. You do not need to contact us for permission unless you’re reproducing a significant portion of the code. For example, writing a program that uses several chunks of code from this book does not require permission. Selling or distributing a CD-ROM of examples from O’Reilly books does require permission. Answering a question by citing this book and quoting example code does not require permission. Incorporating a significant amount of example code from this book into your product’s documentation does require permission.
We appreciate, but do not require, attribution. An attribution usually includes the title, author, publisher, and ISBN. For example: “Spock: Up and Running by Rob Fletcher (O’Reilly). Copyright 2017 Rob Fletcher, 978-1-491-92329-0.”
If you feel your use of code examples falls outside fair use or the permission given above, feel free to contact us at firstname.lastname@example.org.
Safari (formerly Safari Books Online) is a membership-based training and reference platform for enterprise, government, educators, and individuals.
Members have access to thousands of books, training videos, Learning Paths, interactive tutorials, and curated playlists from over 250 publishers, including O’Reilly Media, Harvard Business Review, Prentice Hall Professional, Addison-Wesley Professional, Microsoft Press, Sams, Que, Peachpit Press, Adobe, Focal Press, Cisco Press, John Wiley & Sons, Syngress, Morgan Kaufmann, IBM Redbooks, Packt, Adobe Press, FT Press, Apress, Manning, New Riders, McGraw-Hill, Jones & Bartlett, and Course Technology, among others.
For more information, please visit http://oreilly.com/safari.
Please address comments and questions concerning this book to the publisher:
We have a web page for this book, where we list errata, examples, and any additional information. You can access this page at http://bit.ly/spock_UR.
To comment or ask technical questions about this book, send email to email@example.com.
For more information about our books, courses, conferences, and news, see our website at http://www.oreilly.com.
Find us on Facebook: http://facebook.com/oreilly
Follow us on Twitter: http://twitter.com/oreillymedia
Watch us on YouTube: http://www.youtube.com/oreillymedia
I first began with the intention of self-publishing, but although I had drafted a few chapters, I realized that I needed the encouragement and editorial support of a publisher or I was never realistically going to get the thing finished. So, thanks are definitely due to Brian Foster and Nan Barber at O’Reilly who encouraged me and helped me get the shape of the book right.
Thanks also to the technical reviewers, Leonard Brünings, Marcin Erdmann, and Colin Vipurs, who picked up on problems and provided invaluable feedback.
The decision to write the book was made in a conversation with Luke Daley in my back garden in London. Luke’s work on Geb, Gradle, and particularly Ratpack has been inspirational. He is genuinely one of the most ridiculously smart and productive people I’ve ever met.
Over the course of writing this book, I’ve changed jobs and changed continents. I’ve met and worked with many people who have inspired and encouraged me. Thanks are due to the many fantastic colleagues I’ve had over the years in London:
Dave Townsend at Logica who first introduced me to JUnit many, many years ago.
Simon Baker, Gus Power, Tom Dunstan, Kris Lander, Jerome Pimmel, Kevin Richards, Shin Tai, Dora and Zsolt Varszegi, and the rest of the crew at Energized Work, where I really learned whatever craft I can lay claim to.
Jim Newbery, Sarah O’Callaghan, Glenn Saqui, and Joffrey Tourret at Sky.
…and in California:
Chris Berry, Diptanu Choudhury, Cameron Fieber, Andy Glover, Adam Jordens, Ben Malley, Dianne Marsh, Clay McCoy, Mike McGarr, Chris Sanden, John Schneider, Jeremy Tatelman, Danny Thomas, and Zan Thrash at Netflix.
…and those who seemed to stalk me from one continent to the next:
Nathan Fisher, Tomás Lin, and John Tregoning.
The many people in the automated testing and Groovy communities and beyond who I’ve met at conferences, meetups, or over GitHub and Twitter: Andres Almiray, Jeff Beck, Burt Beckwith, Kyle Boon, Craig Burke, Michael Casek, Cédric Champeau, John Engelman, Danny Hyun, Shaun Jurgemeyer, Guillaume Laforge, Stephané Maldini, J.B. Rainsberger, Graeme Rocher, Marco Vermeulen, Aaron Zirbes, and many more.
Even Dan Woods, who started and finished his own book for O’Reilly (Learning Ratpack) in the time it took me to write this one and never hesitated to remind me of that fact. If you appreciate this book, don’t forget to #unfollowdanveloper.
Above all, I want to thank my kids, Alex and Nicholas, for putting up with a sleep-deprived dad who was already hunched over a laptop when they woke in the morning.