Nov 062009

There’s been a bit of a twitter storm recently, prompted by Cashto’s blog, Uncle Bob’s response, and Justin’s excellent riposte.

So, here’s my response to Cashto’s post. I value unit-level BDD hugely, and it’s fairly intuitive for me. So I’m also going to try putting in some hints and tips about how to get this right, as well as some alternative opinions that I’ve come across recently which surprised me.

I’ll be mixing language here, so that I can respond to Cashto’s language without confusing matters. If you want to use the language of BDD, see my last post.

I’ve snipped bits of your blog, Cashto, because this is already going to be a very long post. Hope that’s OK. I’ve kept your sections in to make it easier for people to read.

(You can skip to the bit where I say it’s Okay not to write unit tests if you want.)

But Unit Tests Work For Me!

First, are you sure you’re really unit testing? Unit testing is all about testing “units”—independent pieces of logic. … If they are any dependencies, they are mocked away. Do your tests do that?

Mostly, yes. I don’t tend to mock out domain objects – I use a builder pattern instead. I’ve also written integration tests which talk to the database or file system.

That’s what I thought. They’re not unit tests, they’re just tests.

I think of them as descriptions of behaviour, together with some examples which illustrate that behaviour. I’m less worried about whether they’re testing anything than I am about whether people can change the code safely and work out what went wrong, if and when it does go wrong.

You probably work on a project that lends itself to easy testing, and your platform likely has great tools for the job.

If you can reuse units of code and and throw an exception when something is false, you’ve got a tool for the job. All the rest is just reporting, and making feedback faster.

You also have great intuitions where the right level of testing is—or if not, you’re at least at that stage in your career where you make lots of little mistakes and the tests you write actually help you catch them.

When I learnt TDD, I was at that stage in my career where I didn’t quite get OO and good design. I was lucky enough to come across BDD fairly early in my TDD learning, and that really helped me realise that TDD isn’t about testing. Most of the confusion I can see in your post comes from that word, “test”. I value BDD because it makes me think about the responsibility of my classes, and where I can appropriately delegate other responsibility.

College students, for some reason, seem especially enthusiastic about unit testing.

Unlearning is much harder than learning. Once a senior developer whom I respect hugely stormed out of the room because I found it so difficult to code without writing tests first, and it was slowing him down. Eventually we realised that I was using them to understand the context of what we were doing. After that I was able to contribute much more productively. If someone really likes their unit tests, they may be doing the same thing – just trying to understand your thoughts and write them down.

But once somewhere around level four of the Dreyfus model of skill acquisition, unit tests start to lose their effectiveness. In fact, they might even be what’s holding you back from further growth.

Training wheels are a best practice—for learning how to ride a bicycle. They’re not a best practice for riding the tour de France.

As I’ve become better at BDD, I’ve started becoming more pragmatic about where I write tests and where I don’t. On my toy projects, if a class can be tested by cursory inspection and it’s covered by something somewhere else – an acceptance test or scenario, maybe – then I might skip it. If in doubt, I tend to write the test. I’ll certainly write something if there’s someone else on the team who needs to understand why I wrote the code I’m about to write. I also use them to help me with the design.

Unit Tests Give Me Confidence When Refactoring!

Unit tests tend to overspecify behavior—they test implementation details that don’t matter, rather than fixed contracts that do.

And they’re too fine-grained.

Many of them will not even survive the <refactoring> process at all. That’s what refactoring means. I’ve never known a significant refactoring which didn’t require the tests to be majorly reworked or even rewritten.

Sometimes I find this is true. It’s not so painful, though, because the design that I’ve created through BDD is simple enough that my class is no bigger than my head, and has maybe four aspects of behaviour. It’s fairly easy to change that behaviour, and the full sentences that I use to describe what I’m testing makes it easy to see what old behaviour I should be changing.

A test that needs to be updated every time the product changes is not really a test at all.

I agree that any such test isn’t really useful. The only reason for having tests is to help you change the product – otherwise you might as well manually test it, treat it as fragile and never change it again. If tests aren’t helping make change easy, there’s something wrong.

Unit Tests Catch Bugs!

Sure, on occasion you remember to test “the failure case”—the caller passed in null or a negative integer as an argument. Never mind that null or a negative argument is an assertable precondition that could never happen in production anyways.

Oh, yes. Don’t do that, people. The rest of the team are bright, intelligent people; if you give them a chance to understand the code you just wrote, they’ll use it correctly. Writing tests to describe why your code is valuable and how to use it can really help here.

It’s also not uncommon for the tests to have the same bugs as the product. And why not? The same person wrote both.

Try pair-programming, and getting one person to write the tests which the other person codes. I’ve certainly blinded myself to my own bugs on my toy projects before. Fortunately my automated scenarios or my manual testing tend to catch this.

Unit testing is no substitute for adversarial testing.

Absolutely, which is why experienced, professional testers are so valuable. They think of all the scenarios we missed. They behave like users determined to break your app. I love those sneaky buggers.

There are so many kinds of failures unit testing can’t find for you … the majority of your bugs are bigger than that, aren’t they?

They do help me fix them more quickly.

Unit Tests Improve My Design!

If anything, unit testing encourages some pretty questionable practices, like making private methods public just for so they can get the code under test…

I keep seeing this. I even saw someone do this in Programming with the Stars. Don’t do this! Write an example of how you’re going to use the code. It’s not about testing individual methods; it’s about the behaviour of an object as a whole. If you need more than one method for a class to be valuable, show how you’d use them in conjunction.

or creating zillions of interfaces for mocking purposes, interfaces that leak implementation details like water leaks through a sieve.

Of course, if you’re writing tests first, you’ve got the interfaces because you have no idea what’s going to implement them, so you’re completely independent of the implementation. Imagine it’s all done by pixies.

Its heart is in the right place when it comes to its rabid stance on decoupling.

TDD as the Cujo of the Agile world…

But there’s a lot of things unit tests don’t teach. You’d never get to Tell Don’t Ask with unit tests alone —in fact a great number of tests involve introspection of state, often in encapsulation-breaking ways.

I do sometimes find I have to revisit the way I’m using my collaborators, once I’ve actually tried to use them from the real code. This is the only time I’ve found that encapsulation breaks; I’m dependent, at least a little bit, on the implementation. I’ve not found this to be much of a problem, though. More modern, BDD-style mocking frameworks such as Mockito (Java) or Moq (.NET) also help to keep things easy to understand and change.

At best, unit testing is a weathered signpost saying “good design practices are somewhere over there”. But it’s no substitute for actually knowing those practices.

BDD, and the language of BDD, helped me to learn those practices. I also recommend Martin Fowler’s “Refactoring” and Eric Evans’ “Domain Driven Design”.

Many are beginning to discover that functional programming teaches far better design principles than unit testing ever will. … it’s shocking the number of code construction bugs which relate somehow towards mutable state

I hear this too. I’ve been trying to learn languages like Haskell. Maybe I should put more effort in here.

If You Can’t Test It, You Can’t Ship It!

Unit testing is not the only sort of testing out there. Don’t make the assumption that if a product isn’t unit tested, then it’s not tested at all.

For some people, in some contexts, it’s okay not to write unit tests. I’ve spoken to a few people who haven’t yet learned to write unit tests, but who are writing excellent code, usually with automated scenarios that test the whole system. This includes one better known member of the Kanban community, who’s been delivering code quickly and successfully for years. I certainly won’t sneer at any team or individual who can deliver working software while enabling change, however it’s done.

Now I’ll give you that some tests pay for themselves. Some of them are so good they even pay a never-ending stream of dividends. But then again, tests can have negative ROI. Not only do they cost a lot to write, they’re fragile, they’re always broken, they get in the way of your refactoring, they’re always having you chase down bogus failures, and the only way to get anything done is to ignore them.

Rather than discouraging people from writing tests at all, I’d encourage them to look at how to get the first kind of tests instead of the second.

But It’s The Corporate Standard!

Then your organization is dysfunctional.

Sorry to be so blunt, but there it is. If it’s any consolation, a lot of organizations have the same dysfunction: they don’t trust their employees to do the thinking. They think they know better than you, and they don’t.

Or, they may recognise that people in their organisation are still learning, and are putting these standards in place to ensure that the team have the space, time and motivation to learn. They may also recognise the value of tests in documenting code, allowing them to move developers between teams more easily, bring in new people, etc.

Good organizations know there are no best practices that apply regardless of context. … It’s a short walk from “the only practice we know” to “the best practice, period”, and before you know it, you’ve blinded an entire organization to better ways of doing things.

Oh, yes. Don’t do that. Question everything, challenge everything – but try it out first.

So What Are You Saying, Man?

I am suggesting that you take a good hard look at the time you’re spending and ask yourself what benefit you are really deriving. …There are so many other ways you can find bugs with less effort.

Possibly. Unit testing isn’t actually about testing, though. The word “test” is such a misleading term; it’s not just about finding bugs. It’s about preventing the bugs from happening in the first place.

Acceptance tests are great too.

The closer to production you get, the more important the feedback loops are. The most important feedback loop of all, of course, is putting the code into production and seeing if it’s as valuable as you think. (I’m learning about other important reasons for doing this too.)

Don’t beat yourself up trying to get 100% code coverage.

Do try to make sure that the rest of your team can find value in your code, understand how to use it and change it safely.

Hope this helps,

It did. These are problems with TDD that I come across frequently. Pretending they’re not there isn’t as useful as addressing them, so I hope my response has helped too. Thanks, Cashto.

Nov 062009

Prompted by the recent twitter storm, prompted by Uncle Bob, Justin Etheridge and Cashto, here’s some sample language that I use when I’m coaching or thinking about BDD, instead of TDD. I’ve found this language really helps people adopt TDD (for my flavour of it!)

More on this soon.

TDD BDD
test example
class under test class we’re describing
method under test valuable behaviour
what to test why is this class valuable?
how to test how do I want to use this class?
interface role
mock collaborator playing <this> role
design responsibility
passing working, providing value
failing should it do what I’ve described?
verify that ensure that
assert that ensure that
returns true / false tells me that…
returns <object> gives me…
implements <interface> provides <the benefit of the role>
pinning the code down so it won’t break making the code easy to
use, understand and change.
100% coverage Please, come change my code. I believe I’ve given you enough information to do this safely.
Nov 042009

I’ve been invited to submit a talk to the Lean and Kanban conference in Atlanta, on how Lean principles have changed the way in which I approach TDD (which of course is BDD for me).

For those of you on this side of the pond, I’ll be rehearsing this talk on November 9th at Skills Matter. This is a free evening, and there won’t be any podcasts or slides released – so it’ll be your only chance to see it this side of April!

Book here if you want to attend.

Please remember that if you’ve booked and can’t come, someone else may be waiting for your place – so send Skills Matter an email to let them know, and they’ll get in touch with the waiting list.

Oct 172009

The paradox of mocking

When we code from the outside-in in BDD, we start with the layer we know – the UI, often graphical – establish collaborators for the UI, establish collaborators for those classes, and work our way inwards until we run out of collaborators we haven’t coded.

We write examples (tests) for each unit of code, all the way down, and we usually express the collaborations with mocks.

The trouble is, we don’t really know how the class we’re about to code is going to use its collaborators. We can only guess. When I actually come to code the class, I often find that I want to use the collaborator in a different way to the way I expected. When I come to code the collaborator, I might find that it needs more information than its consuming class is giving it to do its job properly.

In this case, I have to back up and change the way that I’m expressing the collaboration in the examples. I change method names and signatures for my collaborator according to the things I’ve learnt from actually using it.

I’d rather do this – work out how I actually want to use a class, then change the descriptions – than be forced to conform to the guesswork that I made.

Multi-pair stories

Yesterday, one of the development team said, “If you’re doing XP, you only have one pair on each story, so if you have four developers, you’ll have two stories in play. It doesn’t make any sense to try to limit it to one.”

I’ve heard some of the Kanban community talk about “swarming” a feature; getting a whole team of, say, 8 developers to take it on and complete it in a short time. I’ve also found that some of them prefer not to split up the features as finely as I do, into very thin vertical slices; instead, the teams work on something marketable.

This makes sense, if you’re going to parcel out chunks of code. The idea of slicing things horizontally goes against most of what I teach about how to write stories – and yet, it does allow a larger team to get something valuable out the door more quickly than BDD’s pure outside-in.

It turns out that guessing what might need to happen further down a stack isn’t much different to guessing what happens with a collaborator, before the class is actually written. Realising this has made me revisit my assumptions about the need to do pure outside-in work. So how can we do this and still call it BDD? How can we gain confidence that we’re writing software that really matters, and doing so efficiently?

I can remember occasions at Thoughtworks where we did this – particularly, finishing off features to hit deadlines at the Guardian. Some of the developers at my current client are also working this way, as are others in the industry. So, here are my suggestions for making this work.

BDD for swarms

  • Use scenarios. Having a clear understanding of the feature and a set of scenarios to which the team can work to helps keep everyone focused on the actual behaviour needed. This means it’s less likely that pairs and individuals will write code “just in case”. If in doubt, YAGNI. The scenarios will tell you if you missed something, once all the chunks are integrated.
  • Get something working. Start with the happy path or simplest scenario, and integrate this as soon as you can. This will provide a “backbone” for the rest of the scenarios. It also lets the team play through the different scenarios to test their work.
  • Mock out collaborators. If you need other classes for end-to-end testing, knock up something really simple or use a mock to allow you to get some feedback. For instance, I make a smiley face appear on my Game of Life exercise when I click the button, just so that I can see that the GUI events are wired up. It takes about 5 minutes to do something like this. Name your simple classes in a way which makes it obvious, so that they don’t get mixed up with the production code and can be safely deleted later.
  • Talk to the team. Conversation around what you’re doing will be crucial! If an interface has been defined at the boundary of the code, and you need to change it, go tell the other teams. They’ll be able to adapt to, or at least be aware of, the changes.
  • The rest of the team is your customer. When it comes to the name of a method or the value that’s wanted from that method, the “upstream” team – closer to the outside – trump the downstream team. When it comes to the information that’s required to do the job, the downstream team win.

    List pets = petStore.getPets(String name);

    The upstream team can ask to change the List to a Set, or the name of the method to getPetsByName. The downstream team can say, “Hey, we need the type of pet too; we’ve got a hamster, a rabbit and a kitten all called Snowy.”
  • Prefer code that’s easy to use over code that’s easy to write. If you’re upstream, trust that the rest of your team will be able to solve the problem you’re about to set for them. Keep pushing the complexity down, and remember: Tell, don’t ask.
  • Use examples to drive your code. When you code a module further down the stack without looking to see what’s going to use it, you’re indulging in guesswork. Write some examples of how you expect the consuming class to be using yours, then revisit them when you have more information.
  • Write examples to help other people code. Ideally, the upstream team will provide examples of how they want the collaborator to behave to the downstream team. These examples can be built incrementally, as the upstream team come up with features.
  • Share code. If the teams check in before the code is finished, their scenarios will fail. If they check in examples which haven’t yet been coded, those examples will fail. This won’t be a problem if no one else is modifying the code base; however, if it’s a subset of a much larger team breaking the build can cause havoc, and the habit of keeping builds green is a good one. Try distributed version control, which will allow a team to check in on USB keys or a temporary space until the code works. (There are techniques for getting, say, Mercurial, to work alongside, say, Subversion – mostly by making each system ignore the other). You could also pass around patch files to keep the code in sync.
  • Delete unused code. If at all possible, check the code as it’s being integrated and delete anything which isn’t actually being used or going to be used. This might include things like database columns, layers of abstraction which aren’t actually valuable, etc.
  • Look for quick feedback. If you haven’t integrated your code within a few hours, it’s probably wrong. Making the assumption that it’s wrong should help you want to integrate it more frequently.
  • The more, the merrier! Look over each other’s shoulders as you pass! There’s nothing wrong with tripling or quadrupling instead of pairing, if it means that a pair is more likely to write the right software later.

Edit:

Eric Willeke responded to my post with his own perspective on swarming. I very much like the idea of having the skeleton (the simplest scenario?) ready in time for the rest of the team to get on board.

Sep 052009

I’ve found a few places recently where the word “Test” has been used in combination with the words “Behaviour Driven” (with or without the “u”). Normally this makes me wince; the whole origin of BDD was intended to separate the act of describing behaviour through examples from the act of testing! Part of my self-appointed role in the BDD community is to be the anchor at the far end of that scale – you’ll hear me say “It’s not about testing!” a lot, especially if I’m answering a question about how to use JBehave to produce some particularly complex set of tests.

This post by Elizabeth Hendrickson describes her use of a BDD framework for genuine testing. Here, Elizabeth is acting in the role of a tester, and using RSpec imaginatively to support her work. Testing is a very different discipline to the act of describing what a system should do, or what a class should and should not be responsible for, and I think this example illustrates that point nicely.

If you find yourself struggling with BDD’s language, or wanting to know how to do something with BDD that only makes sense after the code’s already been written, separating the idea of testing from describing behaviour and responsibility may help you work out what it is you’re trying to achieve and express that to others. Testing is crucial to good software development; it may be that you’re doing something else.

Aug 192009

At Agile 2009, Pat Maddox of RSpec will be running a BDD Clinic with me. Between us we have experience with Java, .NET and Ruby code, and we’re willing to look at and learn from anything else. If you bring your work or ideas along, we will be able to give you feedback and maybe make some suggestions for writing more readable or maintainable scenarios, examples and code. I’m hoping that this will be a community event, since the room is quite large – if you fancy yourself as an expert and want other people’s opinions, come along! Feel free to drop in and out of the session at any time; it’s not a presentation or an ordered workshop, and we’re there to be disturbed (if we’re not disturbed enough already).

I will also be running a workshop on giving and receiving effective personal feedback, and judging the Programming with the Stars competition.

We have been asked, as presenters, to provide materials for our sessions. Unfortunately the BDD clinic has capacity for 300 people! So, I’m not going to be able to bring enough post-its, index cards, pens, pencils etc. with me from England. If you’re coming to the clinic and fancy writing down any of our grains of wisdom or the pearls that you form around them, please bring your own. I imagine most of the vendors and exhibitors will have free pens that you can grab (try the Thoughtworks stand, they’re very friendly).

If you’re coming to the Feedback workshop and you can’t remember what you learnt, I should have done my job better. You might want to bring some paper and pens anyway. There’s always room for improvement!

Aug 122009

Dan North and I will be heading up a free introductory BDD talk at Skills Matter’s headquarters in Clerkenwell near Farringdon, London, next Monday. Drinks will follow.

I like working with Skills Matter because they genuinely believe in, and invest in, the communities that surround the subjects they teach. This is part of their ongoing contribution to the BDD sphere; further free talks are scheduled for the rest of the year. I hope this community is as long-lasting as XtC!

If you want to pay them back, come to my BDD developer workshop in October!

Aug 072009

When I first found out about BDD, way back in 2004, I remember TDD being rather like an ant looking for a flower on a tree, and telling all the other ants back at the nest on the ground about the route.

As the ant, I know roughly where I’m going. Sometimes I can even see the flower! But I keep going down dead-ends and having to backtrack. When I finally find the route and try to talk to the other ants about it, it’s hard to remember the direct path.

The mental map I had of my code looked rather like the path I’d taken as the ant. It was never completely clean. I had no flash of clarity; no sense of “This is the right way!”

Contrast that to the feeling I got when I started using the language of BDD (this was just before I realised that BDD also allows me to do outside-in development.)

If I can fly, I can move outside the tree. I can see the flower, then crawl from the flower to the twig, to the branch, to the trunk and down to the nest. The path is clear. I can tell the other ants exactly where I started, and how I reached them. Life is simple and beautiful. I can see how other ants might have become confused. I can see the other routes that might have side-tracked me. I just don’t have to go down them any more.

BDD gives me wings.

Jul 302009

I’ve found myself repeating this a few times lately, so maybe it will help some people out there.

In BDD, we don’t design using mocks.

We design by thinking about context, responsibility, collaboration and delegation, then we use mocks to express that (or stubs, in the case of context).

If we can find a different word to replace mock, stub, test-double, test-spy, etc., we probably should. In the spirit of BDD’s NLP roots, it might help us think differently. There may be more than one word for different uses. Any suggestions?

Jul 012009

While I’m coding, I usually have a bunch of very helpful pixies hanging around my desk. (They’re Dan’s pixies really, since he thought of them first; I’m just borrowing them.)

The pixies are bored, and just waiting for a job to do. So, when I’m coding a class, they look out for opportunities to help out that class. When I’m coding the Game of Life, for instance, I write a Gui class that lets me toggle the cells on the grid. Then I have to work out what happens when I toggle the cells.

I could do it in the same class – in the gui – but fortunately the pixies step in to prevent me making these poor design decisions. “Oh, I’ll do that for you!” one of the pixies calls out. (They usually start with this phrase, and they’re all called Thistle.)

“Thanks, Thistle! Do you know what you’re doing?”

“Um, not really. What’s toggling a cell? Why’s that valuable? What is it you want me to do for you again?”

“I need you to handle the cell living and dying when I toggle it.”

“Oh, okay!” Thistle says. “I don’t like the ‘and’ word so much, though. It makes me feel like I’m doing two things at once. What do you call that? The living and dying thing?”

“Hm.” I think about it while the pixie taps his foot impatiently. “I’d call it a lifespan, maybe. Can you handle the cell lifespan for me? Just let me toggle the cells. I also need you to tell any observers that there have been some changes to the cells, and give them a way of finding out where those changes are. I think they’ve already got an idea of what they want there.”

“Really? Both things?”

“Well, there’s no point doing one if you don’t do the other. It’s all part of the same role.”

“If that’s what’s valuable to you then I’ll do it,” he says. “Just pretend I’m there for the moment; I’ll be back when you need me.”

“Fine,” I say. So I use a mock pixie in place of the real one. I create an interface which does what the pixie’s going to do: IHandleCellLifespans.

(See, it’s an interface that starts with “I”, and it represents a role that the pixie is playing for me. This is a role-based, anthropomorphized interface.)

So, now we have code which compiles. Of course, the real code in the Gui is null, or maybe a null object pattern – I might create something like IHandleCellLifespans.KILLING_THEM_ALL if I’m feeling particularly mean. But that’s all right, because Thistle the pixie will step in when it’s time.

So, I run the code. I’ve usually written an automated scenario. It doesn’t matter whether I run the scenario or step through the game manually; both result in the same thing happening, or not happening – no matter where I click the mouse, no cells appear. Pixies are notoriously unreliable.

Since I can’t rely on the pixies, I inject a new class to handle the dependency instead. I decide to call it the Engine, for the moment, and I write an example of how to use it and what it should do for me.

The next step is the Next button. I think about how this would work in the Engine, and start writing some code to show how the Engine needs to behave. I’ll need to calculate the number of neighbours, and apply the rules accordingly.

One of the pixies pipes up, “Oh, I’ll do the neighbours!” and another one says, “Oh, I’ll handle the rules!”

“Fantastic!” I’m so trusting; I always forget what these pixies are really like when it comes to getting the work done.

“If I’m going to count the neighbours,” Thistle says, “I’ll need some information about where I’m counting from, and what’s around me.”

“Ah, I can get the information from the cell itself,” I say.

“No, don’t do that. It’s fine where it is; I’ll just sit inside the cell and do it from there. Can you give me something that lets me know where the other cells around me are? Then I can do the work for you.”

“Sure,” I say, “the Engine knows where the life is. I’ll just give you access to the Engine and let it play that role for you.”

“Can’t I do it instead? I’m bored,” one of the other pixies asks. “Just give me the information from the engine, and let him talk to me instead.”

“Um, Okay.”

Of course, when I try to run it then I find out that all the pixies have mysteriously vanished, and I end up assigning the role to the Engine anyway, or one of its anonymous inner classes. Having it defined as a different role means that it’s easy to move this responsibility around. Maybe I’ll create a World to look after the cells, and let that do the job instead; the pixies certainly aren’t very helpful.

“What do you mean, we’re not very helpful?” Thistle says. “Look at your code. You haven’t written anything that isn’t needed by something else, so there’s less code to maintain. Because we jump in all the time to try and do jobs for you, every time you can assign a new responsibility to something else, you do – that’s the single responsibility principle in action; none of your classes are doing too much. And you can replace us with something else that does the job at any time – that’s the Liskov Substitution principle. The roles we perform are clearly named. It’s been easy to describe the behaviour of each class using mocks to stand in when we’re not there, and the examples are very readable. You can also use them to work out whether your code still works or not, by running them as tests.”

“Okay. I can’t see myself relying on you guys for bigger, enterprise stuff, though.”

“What do you mean?” Thistle looks offended. Oops.

“Well, let’s say that I’ve got a shop, and I need the tills to talk to stock control.”

“Controlling stock? Oh, I’ll do that!” one of the pixies announces excitedly.

“What, all on your own?”

“Well, I’ll probably delegate it to a team, but that’s my responsibility – you don’t need to worry about it. I’ll be there when you need me. Just pretend I’m there for now. How would you like to find me? What kind of stuff are you going to send to me, and what do I need to do with it? What would you like back?”

So I start with something simple – a URL that I’ll use to find Thistle the pixie, some domain objects that I want to send him, and some objects that I’d like back in return. We talk about how to get the information across, whether some of the tills might provide different stock information, how to talk to the claims department about the quality of the goods we’re selling, and whether I’ll be okay if the claims he gives me have more information than I need.

“Hold on,” I say. “You’ve got me playing this game now. I’m not a Claims Department. I’m not going to do the job myself. I’ve got a home to go to!”

“Meh, never mind,” Thistle replies. “I’ll be sitting with this team over here, coding the stock control. We’ll just pretend you’re doing the job; we’ll mock you out for now.”

“How will I know that I’m doing the job correctly?”

“We’ll have to talk to each other occasionally. Is that going to be hard? We’ll write some scenarios over in our team that describe how we’re going to use you.”

“What if I make a mistake?”

“Do you know what mistakes you’re going to make already?”

“No,” I confess. “I’m sure there will be some, though.”

“When you make a mistake, we’ll deal with it at that point. Sound good?”

I think about it. I reckon I could write some code that pretends to be doing the job of the Claims Department and responds correctly to the way they’ve described how they’re going to use me – just for those examples – then I could go home and Thistle would never know. I knock up a quick stub and slip it into the stock control team’s scenarios, then I disappear too, just like the pixies. I figure I’ll start coding a real Claims Department that does a more robust job tomorrow.

When I get back the next morning, all the pixies performing the role of Stock Control have been replaced with code too. The Stock Control team claim that they’ve never even seen them.

I corner Thistle again. “You’re really not very helpful, are you?”

Thistle looks sulky. “Of course we are! Look at your architecture. You’ve got simple messages going back and forth. Your code is very tolerant of extra information, as is the code on this side. You’ve got lovely RESTful URLs, because you were thinking about how you’d like to find us, instead of us providing you with some weird mechanism that doesn’t match exactly what you wanted. We’ve got clean interfaces and APIs. There are no extra columns in your database, because you only replaced exactly what we said we’d do in the first place. You’ve got scenarios to describe how we work together, and at a unit level examples to describe how you’re delegating responsibility to the other pixies. It’s a lovely, maintainable system with a fairly flat cost of change. Isn’t that what you wanted?”

I nod thoughtfully. “I think it would have been easier for me to just write the code instead of going through you all the time.”

“Ah,” says Thistle, “but then you’d have code that was easy to write, instead of code that’s easy to use.”

I think about how they made me fill in the role of the Claims Department. “You never did any of the work, though! I could have done that job myself; put myself in each of those roles and then replaced myself with real code. That would have let me create consumer-driven interfaces just as easily as using you.”

Thistle shrugs. “If that’s what works for you, sure.”

“Won’t people think I’m a bit mad? If I start talking about how I’m personally going to use a particular class, or how I’m offering to do a job for another?”

Thistle looks at me with raised eyebrows, then gestures at all the other pixies clustered around my desk.

“I think it’s a little late to be worrying about that now,” he says.