DanNorth.net

September 14, 2008

The End of Endotesting?

...or why Mockito is my new friend.

So what’s endotesting?

The pioneers of the technique we now know as mocking presented a paper at the XP 2000 conference, where they first introduced the idea to a wider audience. They prefaced it with the quote:

“Once,” said the Mock Turtle at last, with a deep sigh, “I was a real Turtle.”

The Lewis Carroll reference appeals to me because I often cite Humpty Dumpty as the real creator of behaviour-driven development:

“When I use a word, ” said Humpty Dumpty in a rather scornful tone, “it means just what I choose it to mean, neither more nor less.”

These folks – Tim Mackinnon, Steve Freeman and Philip Craig – realised that you could drop in a fake instance of an object that you could get to “fail fast” if it received a method call it wasn’t expecting:

We propose a technique called Mock Objects in which we replace domain code with dummy
implementations that emulate real code. These Mock Objects are passed to the target domain
code which they test from inside, hence the term Endo-Testing.

This approach – endotesting – led to the creation of a number of open source frameworks, most notably JMock (written by Tim and Steve among others) and EasyMock. The basic premise of these frameworks was to make it easy to create a mock object and prime it with a number of expectations. (Your makeCheese method will be called with the parameter "brie". When this happens, return the value BRIE.)

Having set up a mock object with its expectations, you wire it up into a bunch of objects and then poke the outermost object. If all goes well you can interrogate your mock and it will tell you its makeCheese method was called. If it doesn’t go well – well that’s when the magic happens. If you call an unexpected method on a mock it will fail during the test, giving you a stack trace from exactly where the unexpected method call happens. You don’t have to start rummaging through the call sequence trying to work out where it all went wrong, and your test doesn’t carry on running after the unexpected method call to produce a bogus result that doesn’t make any sense.

How we use mocks

Now if you are wiring together a complex group of objects to do something, endotesting-style mock objects are invaluable. I had a situation a while ago where we had a suspect XML message being sent over the wire to an external system. We wrote an integration test where we injected a mock for the external system into a complex object structure – the mock was primed to only accept a valid XML message – and when it failed the stack trace gave us a direct line into the failure. It turned out one of the eight objects wired together was doing an incorrect transformation on part of the XML which meant the outbound message was invalid. By using a mock object in this way we were able to identify exactly where the error was occurring.

However nowadays mocks are mostly used for describing interactions between objects in the context of test-driven development. Your object under test interacts with one or two other objects that you represent by interfaces (roles) that you probably inject into its constructor as mocks. Your test is verifying that the object calls the appropriate methods on its collaborators. In this simplistic scenario, the reason for a failure is usually pretty obvious – you haven’t written the code yet or you are passing the wrong parameters into the method call.

Say you are developing a simple calculation where you expect the answer to be 7 but the code is producing the answer 10, then it isn’t that difficult to work out where the problem is. You don’t need the code to fail as soon as the value of 10 is produced. The fact that the answer is 10 and you expected 7 is enough to triangulate the error. This is classic post hoc state-based testing. Similarly, if you expect your object to call makeCheese on the CheeseFactory and it doesn’t, well you are likely to have a pretty good idea where it doesn’t. So all you really need your mocking library to do is act like a flight recorder black box. You can ask it after the fact: hey CheeseFactory, did my object call your makeCheese method? If it didn’t you probably know why. (And if you don’t it may be an indication that your test is too complicated.)

A more intuitive approach to mocking

This then means that you can treat assertions on method calls just like you treat assertions on state changes, asking the various collaborators what happened after the fact rather than priming your mock objects ahead of time, which in turn means you don’t need to turn your brain inside-out creating a flow like this:


  // Given
  // ... create mocks
  // ... wire up my object

  // Expect (eh?)
  funky.dslWith("stringsForMethods")

  // When
  myObject.makeBrie();

  // Then
  verifyExpectationsSetTwoParagraphsEarlier(); // you remember right?

 

where it is much more intuitive to write something like:


  // Given
  // ... create mocks
  // ... wire up my object

  // When
  myObject.makeBrie();

  // Then
  verify(CheeseFactory).makeCheese("brie"); // how nice is that?

 
rent a car bulgaria

This, then, is the premise of Mockito. It uses a similar syntax to EasyMock – which means my generics-aware IDE is able to do proper completions and refactorings – but it doesn’t have any of that record/playback nonsense. Nor does it require me to do any of the clever {{ anonymous constructor }} gymnastics that JMock 2 introduced. It just sets up mocks on interfaces (although it allows me to mock concrete classes which I think is a retrograde step – remember kids, mock roles, not objects) and gives me a black box recorder that I can interrogate after the fact.

When I asked Mockito’s author, Szczepan Faber, how he came up with the insight that mocking in the context of TDD was a completely separate problem from endotesting, he replied: what’s endotesting?

It turned out that in order to create a mocking framework to support TDD it helped to have no idea where the encumbent frameworks – JMock and EasyMock – had come from. In the same way that a unit testing framework got co-opted as the enabler for TDD in Java, an endotesting framework became the enabler for method assertions in interaction-based testing. But if you start from the ground up – with a nod to EasyMock and with a pragmatic dose of Java 5 generics – you can get a simple, elegant and intuitive framework for verifying interactions between collaborators. There’s still a place for traditional endotesting in the context of gnarly integration tests, but I’m liking Mockito. I think you will too.

Filed under: Uncategorized — Dan North @ 11:41 pm

September 8, 2008

JBehave 2.0 is live!

Some ancient history

Back in 2003 I started work on a framework called JBehave. It was an experiment to see what JUnit might have looked like if it had been designed from the ground up for TDD rather than as a unit testing framework. I was also starting to use the phrase “behaviour-driven development” to describe what I meant. The jbehave.org domain was registered and the first lines of code written on Christmas Eve 2003, much to my wife’s bemusement. Over time JBehave grew a much more interesting aspect in the form of a framework for defining and running scenarios, or automated acceptance tests.

Since JBehave wasn’t based on JUnit there was always going to be a barrier to adoption in the form of IDE integration and build tools, among other things. It also failed the First Law of Frameworks in that it wasn’t harvested from real life – it was just an extended thought experiment. As a result it turns out it was a bit of a cow to use. Mea culpa.

Some recent history

Many of the ideas from JBehave have since appeared in other BDD frameworks, particularly in the lovely rspec. Although I wrote the first cut of the scenario runner in rspec it has since been thoroughly reworked and improved beyond all recognition1 by the efforts of David Chelimsky and his team. The biggest single improvement has been the introduction of plain text stories, which allow you to separate the scenario text from any of the automated steps they refer to.

Over the last few months, Liz Keogh and Mauro Talevi have completely rewritten JBehave from the ground up, taking advantage of new Java 5 language features and using JUnit 4 as the underlying execution framework.

By using real project examples to drive the design – including using it in their day jobs – they have produced what I believe is a powerful and very usable behaviour-driven development framework for Java. In particular Liz decided she wanted plain text scenarios and the idea of a “pending” scenario – something that you have identified but not yet implemented.

And now…

We’ve released it! JBehave 2 has only been live for a few days and already ThoughtWorks colleague Ryan Greenhall has written an excellent tutorial demonstrating how to use it. Quoting the release announcement on the site, JBehave 2 supports the following feaures:

  • Plain text scenarios
  • Support for multiple scenarios in a file
  • Pending scenarios (the “Amber Bar”)
  • Clear, easy-to-read output from failures and pending scenarios
  • Maven support
  • Parameter capture from scenarios
  • Conversion of parameters to your own objects
  • Support for multiple languages and scenario terminology
  • A high degree of configurability

    Go download JBehave 2 and take it for a spin, and let me know what you think. The mailing lists are waiting for you too.

    1 Aslak Hellesøy is currently working on a replacement for the rspec scenario runner called Cucumber which looks very promising.

Filed under: Uncategorized — Dan North @ 12:23 am

June 30, 2008

Let your examples flow

Should examples/tests/specs/whatever be DRY? I’ve been thinking (and talking and arguing) about the value of test names recently and whether they are just unnecessary duplication, but that’s the subject of a future discussion. This is about the actual content of your examples. So, should your examples be DRY?

In a word, no. DRY zealotry is a classic example of an over-adherence to Best Practices, which as James Bach argues are a bogus concept anyway. When you are writing software, including executable examples, your focus should be on clarity of intent. If the code could be any more obvious, you’re probably not done yet. And given that code is created once but read and changed many more times, it is healthy to develop a strong sense of responsibility to the guys coming along after you.

In tests, flow trumps DRY

The DRY principle says that the definition of any concept should appear once and only once in your code. This is an admirable aim in that if you have to change the behaviour of a Flooble, you want to be able to change it in one place and be reasonably confident that your change will apply consistently across the codebase. If there are multiple definitions of a Flooble, the chances are that not only will you not catch them all, but that someone before you didn’t catch them all and the multiple definitions are already inconsistent, and who wants that?

However, when you are using examples to drive your code – a process I call Coding By Example but which most other people insist on calling Test-Driven Development – there is another principle in play that I believe trumps the DRY principle. The examples tell a story about what the code does. They are the documentation narrative that will guide future programmers (including yourself when you come back to change this code in three months time and you’ve forgotten what it does). In this case, clarity of intent is found in the quality of the narrative, not necessarily in minimising duplication.

Some years ago I had my first experience of pair programming with Martin Fowler. That is, I had done quite a bit of pair programming, just not with Martin before. We were looking at some ruby code I had written test-first, and Martin asked to see the tests, “to find out what the code does”. Then he did a rather odd thing. He started moving the tests around. I had a few helper classes and utility methods in the source file, neatly at the end out of the way. He moved them up and dropped them inline just ahead of the first test that used them.

Madness! I thought – now the supporting code is all over the place! It really offended my sense of tidiness. But then I saw a pattern beginning to emerge. The test code was starting to read like a story. He would introduce these little methods and classes just before their one walk-on line in the narrative. It was quite an eye-opener for me. The test code flowed, and unfolded the story of the class under test. (I know I’m using TDD vocabulary – this was in my pre-BDD days.)

Go with the flow

The A-ha! moment for me was when I imagined reading a story book where the plot and characters had been DRYed out. Everything would be in footnotes or appendices. All the character descriptions, plot elements, subtexts etc. would be carefully extracted into fully cross-referenced paragraphs. Great if you are “reading” an encyclopaedia, not so appropriate if you want to get into the flow and find out what happens. You would be forever flicking back and forth in the book and you would very quickly forget where you even were in the story. In the words of the old joke, a dictionary has a lousy plot but at least they explain all the words as they go.

So here’s my challenge to you. When you read through a test case, or spec file, does the story unfold? Does it start by introducing the object’s most important responsibilty? Does it then introduce the edge cases in descending order of priority? If the test uses helper classes and methods are they tucked away at the end, or worse yet in an entirely different file that I am expected to “just know” is there?

Try to avoid using before blocks or setUp methods – especially in an abstract test class. Just call the method that does the setting up directly from the example. Don’t leave me to guess there might a magic method in a different class that is being invoked before the test even runs – that’s just not fair.

Also thanks to Mikel Lindsaar from the rspec mailing list for an excellent article about the perils of slavishly following DRYness.

Filed under: Uncategorized — Dan North @ 11:55 pm

June 29, 2008

Learning to Lean

A discussion unfolded recently on an internal mailing list that tied together two of my favourite topics, namely learning theory and Lean.

Someone was asking how they might apply Lean to setting up and running a new project. A number of people made suggestions, all of which were the kind of good common sense I would expect from my ThoughtWorks peers, but what particularly struck me was the way the answers exemplified the different stages of the Dreyfus Model of Skills Acquisition. (The link is to an interview with pragmatic programmer Andy Hunt, whose forthcoming book Pragmatic Thinking and Learning contains an excellent chapter on it).

The Dreyfus Model of Skills Acquisition

As well as providing a useful description of each stage of learning, the Dreyfus model describes how best to help the learner progress to the next stage in their learning.

According to the Dreyfus model there are five distinct stages, as the learner gains experience and develops insight and intuition. Very briefly:

The Novice wants recipes, best practices, quick wins
The Advanced Beginner wants guidelines, a safe environment to make mistakes
At the Competent stage you want goals, freedom to execute
The Proficient learner wants maxims, war stories, metaphors
The Expert wants philosophies, discussions and arguments with other experts(!)

So back to the mailing list discussion, here’s what I saw in amongst a number of responses. (I’m paraphrasing and summarising for effect.)

Novice: I like the sound of Lean and I want to apply it to my next project. Where should I start?
...
Competent: Here’s my cheat sheet of Lean practices and behaviours.
...
Expert: Lean isn’t a process, it’s a philosophy.

Perfect!

So why such a wide spread of different answers? The problem is that when it is applied to software delivery, Lean is a metaphor, which means it’s too abstract for a novice to “just use” without making it situationally specific, and too concrete for an expert to articulate easily. For example, the Lean concept of inventory applies in a number of subtle ways to software delivery.

It is worth mentioning that the Dreyfus model is about describing the acquisition of a specific skill – in this case applying Lean theory to software delivery – and not a general categorisation of an individual. For instance the author of the reply from which I took the “competent” fragment above is an accomplished agile coach and developer, so be careful not to take the Dreyfus descriptions out of context. (But you wouldn’t do that, would you? I meant the others.)

Getting started with Lean

So then I thought, what would be the most useful advice to an experienced Agile team lead to get started? To kick a project off in a Lean way, I would suggest the following:

1. Get everyone immersed in some Lean theory. Use workshops with lots of interactive exercises. Be aware they are at the novice stage so they will find rules and recipes – and quick wins – more useful than context at this stage, even if the specifics aren’t strictly correct. “It depends” is never helpful here. Ship in your local Lean expert – Richard Durnall or David Anderson in my case – and steal some collateral from the intertubes. Share with the team that you’re new to this too – it will make them less afraid.

2. Think about how Lean applies to software delivery. For instance, there are three “flavours” of Lean, namely Manufacturing, Supply and Product Design. Although they all focus on minimising waste, they also have specific targets in mind.

  • Lean Manufacturing is about minimising variance (you want all the cars to come out the same). This is analogous to build, deployment and running automated test suites. The same code should always produce the same deployable artefacts. Test runs should be idempotent (rerunnable with the same results).
  • Lean Supply is about minimising inventory. This is analogous to deferring decisions, doing enough up-front analysis and design but no more (and certainly not none, otherwise you starve your supply). Have a nominal backlog of features but don’t bother planning out 3 months of detailed Master Story List (that term should never have made it out of the gate). Carry out exploratory testing soon after the feature is code complete, when it’s still fresh in the developers’ heads.
  • Lean Product Design is about maximising discovery. Everything is an experiment, and if you don’t learn anything it wasn’t useful. This is analogous to writing software, understanding and articulating requirements, user experience workshops, designing effective tests, identifying corner cases. Foster an environment where it’s ok – in fact encouraged – to try new stuff “just in case”, or run two or three ideas in parallel to see which one fits best. That isn’t waste, it’s a good discovery habit that you can position as due diligence. Read up on innovation techniques and creating an innovative working environment. Your programmers aren’t building cars – they’re designing cars. Let them. Make it fun.

    As a example of mis-applying the metaphor, methodologies like six sigma mistake innovation (discovery) for waste (variance) so they squeeze the innovation right out of the process. (They call innovation, sorry variance, “defects” – cute.)

    3. Break down your process into swimlane steps. It doesn’t matter whether it’s right (it won’t be) or whether it fully describes your process (it won’t). What matters is that people are thinking in terms of moving something from an idea to signed off, deployed code (“from concept to cash” as Mary Poppendieck describes it). Use simple index cards to represent work on a big visible wallchart. Moving a card across swimlanes is a small win. People like frequent small wins.

    4. Keep track of where the cards back up. This is a clue to bottlenecks. It may not be that the backlog itself is the problem – it’s just a starting point for your investigation. Apply a systems thinking approach – what could be causing that? What else?

    5. (once you’re getting the hang of it) Apply Lean thinking to your process itself. That’s one of the cool things about Lean. It’s not just about getting work done – it’s about getting better at getting work done. This is when you start looking at your process and identifying the actual value stream as opposed to “the stuff you do”. Are there activities that are just there because “we always do that”? Are there things you spend time on that are so “obvious” you didn’t bother capturing them as their own swimlane?

    There’s a ton of literature out there about Lean – and some of it is quite good – and a small-but-growing body of Lean practitioners within the software industry. We can’t actually clone Richard Durnall, but we can learn from him. As long as we choose to believe we’re always learning, we should be in pretty good shape.

    ps. Another quote from the Lean expert on that email thread – Richard again – was that there aren’t Agile projects or Lean projects, “there are just projects”. This reminded me of a famous Bruce Lee quote. “Before I studied the art, a punch to me was just like a punch, a kick just like a kick. After I learned the art, a punch was no longer a punch, a kick no longer a kick. Now that I’ve understood the art, a punch is just like a punch, a kick just like a kick.”

Filed under: Uncategorized, coaching — Dan North @ 12:51 am

June 18, 2008

Raising money for Leukaemia Research

Right now I have a whole pile of blog articles backed up that I’m in the middle of writing. This post jumped the queue because it is by far the most important.

Leukaemia and other blood cancers are the main cause of cancer death in the under 35s (a demographic of which I am sadly no longer a member, but some of my best friends are under 35). Leukaemia itself is the most common form of cancer in children in the UK.

On 13th July – only three weeks away – I will be taking part in the 2008 London Bikeathon, cycling 26 miles (about 42km – coincidence? I think not) through East London and out the other side. And back.

Please sponsor me – as much as you can spare, or as little as you can find. If you are in the UK, tick the appropriate boxes and our fine tax officials will donate an extra 25% on top of your donation.

Thank you.

Filed under: events — Dan North @ 10:32 pm
Next Page »

Powered by WordPress