Dec 102008

Mike and Gabriel both posted comments to show how the Cowhand example in my last post might look and evolve with different mocking frameworks. They’ve used FluentSpec and Rhino Mocks respectively.

Thanks, Mike and Gabriel! It was a pleasure to find these snippets waiting.

Also, Olof suggested that I include something a little less farm-related, so I’ve added another example with Mockito*, too. Thanks, Olof!

*Mockito’s syntax is now even better than this, but this is the syntax I’m used to.

Dec 102008

Some of us have taken to writing comments in our BDD classes to give us Given, When, Then at a unit level.

So, if I’m writing examples for a cowhand, I might write something like this:


public class CowhandTest {

public void shouldMilkTheCow() {

// Given a repository which knows about one cow
CowRepository shed = mock(CowRepository.class);
Cow daisy = mock(Cow.class);
stub(shed.getCowByName("Daisy")).toReturn(daisy);

// Given a cowhand who knows where the cows are kept
Cowhand cowhand = new Cowhand(shed);

// When I ask the cowhand to milk the cow
cowhand.milkCow("Daisy");

// Then the cow should have been milked
verify(daisy).milk();
}
}

(updated) Olof rightly suggests that cows may not be the clearest way to explain this, so here’s another:


public class LoginControllerTest {

public void shouldRedirectSuccessfulLoginsToTheHomePage() {

// Given an authenticator which allows the user to log in
Authenticator authenticator = mock(Authenticator.class);
stub(authenticator.login("Fred", "P@55word")).toReturn(true);

// When the controller gets Fred's login attempt
LoginController controller = new LoginController(authenticator);
HttpResponse response = controller.attemptLogin("Fred", "P@55word");

// Then the response should redirect us to the home page
assertTrue(response.isRedirect());
assertEquals("/home", response.getRedirectUrl().toString());
}
}

Occasionally I’ll run across something that needs to be explicitly captured in a step as a method; mostly this is sufficient. The audience for the class-level steps is technical, so this works.

You can think of each class as having a stakeholder, or consumer, which is usually another class. There will be something, somewhere in the codebase that uses my Cowhand, or my LoginController (or I probably don’t need to write it yet). The exceptions are GUI classes; their stakeholder is the user.

You’ll notice that I’ve mocked out my collaborators – the CowRepository, or the Authenticator (using Mockito, because it doesn’t require expectations to be set so it allows me to keep the G/W/T flow).

I may not have written the real Cow, CowRepository or Authenticator class yet. This may be the first time I’ve decided that I need one. In that case, by the time I come to code the class, I’ll already have some examples which describe how I expect it to behave.

Dec 022008

Spurred by Dave Anderson’s blog pointing at Tobias Meyer’s blog

I once told this story to a group of people I was training as coaches.

The problem with Waterfall

Once upon a time some people noticed that their software projects were failing to deliver what the business needed. “We should be clearer about what we need,” someone said, “and check that those needs are interpreted correctly all the way down until we reach the code.”

And when things still went occasionally awry, they said, “You’re not doing it hard enough! Get more detailed requirements before you start work! Spend more time getting the design right! Don’t start coding until you’re sure!”

And when things still went awry, they said, “Do it even more!”

And that’s how we got Waterfall.

The problem with Scrum

Once upon a time some people noticed that their software projects were failing to deliver what the business needed. “We should assign someone to be the product owner, who can express what’s needed,” someone said. “We should have a stand up every day, a planning meeting at the beginning of each sprint and a retrospective at the end. And burndown charts.”

And when things still went occasionally awry, they said, “We should put someone into the teams who knows how to do this better, and who can make sure that everyone is following the rules properly. And we should give them certificates!”

And when things still went awry, they said, “Do it even more!”

And that’s how we got Scrum.

The problem with XP

Once upon a time some people noticed that their software projects were failing to deliver what the business needed. “We should assume that we’re wrong to start with,” someone said. “We should keep the cost of change low. We should do acceptance and unit testing, integrate continuously, maintain collaborative ownership of the code, and be courageous, respectful and communicative, keep things simple and get regular feedback about how wrong we are.”

And when things still went occasionally awry, they said, “We should automate more acceptance tests, and reduce build times, and automate deployment, and if anyone doesn’t like it we’ll make them pair program! Turn the dials up to 10!”

And when things still went awry, they said, “Do it even more!”

And that’s how we got XP.

Some good things about Scrum, XP and other Agile methodologies

According to the Dreyfus Model, novices – those learning practices for the first time – really value a step-by-step approach. They don’t necessarily know which steps are important. Patricia Benner, in her book “From Novice to Expert”, describes how novice nurses will follow every item on their checklist, for each item.

This is a great way to start learning. However, with experience and practice comes an intuitive knowledge of what’s important, what’s not, and what you can do to get a similar value from your practices. For instance, a competent nurse will spend her first ten minutes on the ward checking that nobody’s dying, before worrying about the bedpans.

Once we become experienced in a methodology, we start to put the focus on the things we find important, and find alternatives for things which are hard. I’ve worked on XP projects which had no automated acceptance tests, but great QAs. I’ve seen people refuse to pair-program, but happy to review each others’ code. Things do sometimes fall over in these projects – that’s just life! It isn’t necessarily because the practices aren’t being followed. Sometimes it’s part of a learning experience, and something to be celebrated, because it means people are trying things out and willing to be surprised.

The problem comes when we see things fall over, and try to prevent them by adhering rigidly to our steps, no matter what. They’re there for novices. They’re not intended to work for everyone all of the time, or even for most people, most of the time. They’re just a good starting point. As soon as we depart from those steps we’re in uncharted territory, and should expect to find things out. In my experience some of these findings are painful; most of them are delightful.

So, next time you find yourself arguing about what makes a good methodology, and which methodology is best, you could try asking, “Who for?” It might get rid of some of those arguments.

Why Lean is different, and the same

Lean’s a meta-methodology. It’s a methodology that you can apply to other methodologies after your step-by-step practices have become stifling. Techniques such as Value Stream Mapping, as well as principles like minimising waste and root cause analysis, can be applied to any project, no matter which methodology it started with.

I’ve done this, quite successfully and in combination with a bunch of other tools. I don’t have much experience with Lean, and was still quite surprised at how much I learnt just from reading some books and talking to some people who’ve worked in Lean manufacturing and Kanban software teams. I particularly liked the Poppendieck’s books. Scrum also has merits, and I understand the desire to keep the mailing list suitable for novices – maybe it’s time for another mailing list. XP is still the core methodology I prefer to start with – thanks Kent Beck. I also found sensible practices in common sense, patience and valuing other people’s opinions.

Lean is a step-by-step approach for me at the moment. I have no doubt that if I try to apply this blindly to every Agile coaching gig that comes my way, I’ll find the limits of Lean just as I’ve found the limits of Scrum and XP.

The problem with Waterfall, Scrum, XP and Lean?

Probably isn’t with Waterfall, Lean, Scrum or XP. Except for Waterfall.

It probably isn’t even with the people, either. We’re human, and we’re all at different levels and stages of learning. Different practices are appropriate for different people, in different situations. Why not try a few, and see which ones work best?

Then next time you hear someone evangelising some particular practice over another, you can smile, and nod, because you know where they are in their journey, and perhaps you even know where you are in yours.

Dec 012008

Back last year, Vlad Gitlevich kindly made a video of Dan and I talking about BDD.

We concentrated almost exclusively on the principles rather than the technology, which means the video is still very relevant. Particularly we talked about how BDD plays with DDD, outside-in, stories and scenarios and using them in conversation with the business, and our own experiences.

See it here!

Thanks, Vlad!

Dec 012008

Antony Marcano’s written a great post on testing for exceptions in a way which makes the example much easier to read, and keeps the Given / When / Then flow intact. I like this very much, and will be doing it this way from now on (aversion to defensive programming notwithstanding).