Slimmed Down Software – A Lean, Groovy Approach Part 1 – Eliminate Waste
This article originally appeared in the April 2010 edition of GroovyMag, the Groovy and Grails magazine. Parts 2 and 3 are currently available for download from the magazine’s site, and more will come each month. Enjoy!
The Groovy Programming Language advertises itself as an “agile and dynamic language for the JVM”, but what does this mean exactly? This series of articles explains Lean Software Development, and shows how your choice of programming language can make your entire process remain nimble and adaptive. Each month will cover one of the seven Lean Software Development principles and explain how Groovy and the associated ecosystem help eliminate waste, defer commitment, and build quality into your product.
About This Series
Most of your agile team will spend the majority of their day working with a programming language, making it one of the most important tools to optimize in your project’s life-cycle. Yet many organizations are reluctant to experiment with newer languages and frameworks, instead preferring to apply what works in one domain to all domains. They are skeptical about the claimed productivity gains from polyglot programming, concerned about the educational investment of retraining their developers, and worried about the risk of using less proven technologies.
Some languages are truly better than others for certain types of problems. These articles exist to help you identify which domains in your project are most in need of a little Groovy magic as well as to help you sell Groovy to a skeptical or unconvinced audience. Hopefully you will see that Groovy is a great fit for your software life-cycle: its dynamic and expressive nature brings greater productivity to testing and operational support, its closeness to Java minimizes educational investment, and its tight integration with the JVM platform allows you to slowly phase in Groovy without an all-or-nothing decision, making its use a low risk decision.
Groovy is an agile programming language. In order to explain what this means, these articles are structured around the seven principles of Lean Software Development. This month includes a short introduction to Lean, and you’ll see how an expressive language can eliminate waste in unit testing. Next month you’ll see how the easyb Behavior Driven Development framework builds quality into your software development life-cycle. Later we’ll explore how different testing tools like the Spock Framework help create knowledge, how a dynamic language lets you minimize coupling and defer commitment, and how metaprogamming allows you to deliver your software fast. In future installments you’ll see how Groovy’s Grapes module system, alongside modules like Groovy Web Services, streamline interactions between your development team and other groups like Operations and QA. Finally, we’ll look at how Groovy can be applied to domains that cross departmental boundaries: how Gradle improves the build process and easyb facilitates collaboration and communication between team members and other stakeholders. The series will end with a discussion of best practices when mixing Java and Groovy
Some of the code examples are basic while others are advanced. This series explores why the features of Groovy are important rather than the mechanics of any one Groovy feature. Hopefully you’ll leave with some new ideas about how to use Groovy, how to convince your team that Groovy is worthwhile, or most importantly how to increase your productivity.
Lean Briefly Explained
Lean manufacturing grew out of the influential Toyota Production System, which was a set of both philosophies and practices designed to weed out waste, inconsistency, and overburden from a manufacturing process. While the Toyota brand recently took a beating for some public quality failures, it is hard to ignore several decades of successful engineering sensitive product development. In the late 1990′s, Mary and Tom Poppendieck took their knowledge of Lean and applied it to a software project, eventually resulting in 2003 with the publishing of the excellent book “Lean Software Development”. The Lean principles have been revised over time; for our purposes we will use the seven principles from “Implementing Lean”:
- Eliminate Waste
- Build Quality In
- Create Knowledge
- Defer Commitment
- Deliver Fast
- Respect People
- Optimize the Whole
Lean has been an influential movement within the agile community, spawning a plethora of books, workshops, and articles. Besides being a meaningful set of practices in its own right, it has also directly influenced other agile family Members such as Kanban Software and Real Options. Lean is a set of principles first and a group of practices second. The principles are specific enough to align a team but broad enough to appeal across an organization. I once spent a three-hour car ride discussing eliminating waste with the senior manager and director of my development group, and then arrived at work to help an eager development team make practical changes to reach the goals we had discussed. Compare that to a methodology with principles of “Honesty” and “Communication”. I have
yet to find a use for vague principles beyond their ability to make me feel a little better about a crummy process.
Principle 1 – Eliminate Waste
Taken literally, it is easy to see how Groovy fulfills the Lean mandate to eliminate waste: list and map literals, a terse closure syntax, and even a lack of semi-colons means there is simply less keyboard typing to do for Groovy developers. But that isn’t what Lean means by eliminating waste. The real waste within the software process is in half done work. Work that has been started but not delivered eats up the time investment from developers but does not provide value to the client. Any work that has been started but not completed is a form of waste, and we must optimize our life-cycle to keep our user stories out of this state! This means moving stories to Done faster, and any good agilista will tell you Done isn’t done until the unit and acceptance tests pass. Having used Groovy as a testing language on several projects in the last few years, my team’s experience is that the same test coverage and quality can be reached with Groovy in less time than it takes using Java.
Good unit testing means testing not just the success scenarios, but also the failure scenarios and the edge cases where things just barely pass or just barely fail (bugs do tend to congregate in corners, after all). This means your unit tests have to create data, and lots of it. Much more data than your production code needs to create. And Groovy is a language better optimized to create data than Java. Consider the data driven test in Listing 1.
public void testSimpleMath() {
[ 4: { 2 + 2},
6: { 2 + 2 + 2},
8: { 2 + 2 + 2 + 2},
].each { expected, actual ->
assert expected == actual()
}
}Listing 1: A Simple Data Driven Test
The example shows a few ways in which Groovy is different from Java. Should read: First, a Map is declared using the notation [key1: value1, key2: value2, ... ]. So in the above example there is a map of type Map<Integer, Closure> with three entries, which sure beats having to use new HashMap().
The values of the map are Closures, which are function objects. The closure can be executed and passed arguments just like formal methods. They can also be passed around to other methods, returned from methods, and assigned to fields. Very, very powerful. Think of them as Runnable or Callable objects without the awful syntax.
Finally, the each method is just a method on Collections and Maps that iterates over the collection, executing the attached closure once for every element. You can see how this closure runs a simple assertion, asserting that the integer key of the map equals the evaluated value of the map.
With a minimum of non-essentials, this test creates a dataset to be used as test input and then executes the test against that input; it is a data driver test, without a framework, without needing to hide any of the mechanics of the test, and without a bunch of annotations and factory methods. Data driven tests are so easy to write in Groovy that you end up using them far more often than in Java.
Listing 2 is another data driven test with a more useful assertion than simple arithmetic:
public void testUserService(userService) {
[ user1 : ["John", "Doe", 123456],
user2 : ["Jane", "Doe", 654321],
user3 : ["John", "Smith", 789987],
]. each { username, userData ->
def user = userService.get(username)
assert user.firstName == userData[0]
assert user.lastName == userData[1]
assert user.id == userData[2]
}
}Listing 2: An Advanced Data Driven Test
This time the data is a map of Strings to a list of values (within Maps, unquoted key value are treated as Strings, so user1 and user2 are Strings). Java purists will notice that the generics of this expression are not easily expressed in Java, while they can be ignored in a dynamic language like Groovy. In this example the assertion block is simply pulling elements out of the list using the subscript operator [0] and [1] instead of the List#get(int) syntax.
The point is that the Groovy language features (list and map literals, closures, good iteration functions) allow you to write data driven tests more quickly, which in turn means you cover more edge cases and more failure scenarios as well. The minimal syntax of Groovy allows you to get down to the essence of a unit test: clearly show the input, execute the system, and clearly assert the output. Sure, you can Extract Method in Java until you have something with minimal accidental complexity (maybe even “extracting until you drop”), but as Alan Shalloway says, “There is a big difference between eliminating waste and not creating it in the first place.” With Groovy you will write tests faster and you will have your story cards spend less time in the “in process” phase. This is good for your project and good for your customers.
* “Extract Until You Drop” is a blog post from the inimitable Uncle Bob Martin about taking Extract Method refactorings to their logical, if absurd, conclusion. The piece could just have easily been titled, “Writing Clean Code in Java is a Complete Hassle”.
What happened to assertEquals?
Sure, using Groovy’s assert makes your tests more terse, but more importantly check out the exception message on a failing assertion in Listing 3.
def one = "1" def two = "2" assert one + one == two
Listing 3: Groovy Assertions
Treating addition as String concatenation is endearing when your four-year-old is learning arithmetic but is an error in most mathematical systems. Listing 3 is interesting because of the exception message: each element of the expression is clearly expressed in the monospaced message: all three variable references as well as both the operators (+ and ==). Lower ceremony, clearer tests, easier debugging.
Next Steps
One particularly useful Lean practice for eliminating waste is Value Stream Mapping. Sit down at a whiteboard with your development team and write out your software process: the steps and time it takes to move an idea from inception to customer delivery. Where are the bottlenecks? What are the delays? Why does it take so long? Visualizing and quantifying your process helps everyone clearly see problem areas. And who knows, maybe a few Groovy scripts here and there can cut days out of your cycle. Stranger things have happened.
Next Month: Build Quality In
A lean, stream-lined development cycle with minimal waste is nothing if quality suffers. Next month’s article explores how Groovy helps you build quality into your development life-cycle. Instead of inspecting your product for defects after it is built, change your process to not create the defects in the first place. Easier said then done. Luckily, Groovy programmers can use great tools and techniques like easyb, Behavior Driven Development, and builders to build quality into their products.
Learn More
The world is overflowing with books and articles about agile development. These three books are classics and deserve a permanent spot on the bookshelves of discerning programmers.
- Implementing Lean Software Development – Poppendieck
- The Pragmatic Programmer – Hunt and Thomas
- Extreme Programming Explained, 2nd Edition – Beck and Anders










