Six thinking hats

I’ve been wanting to try out Edward de Bono’s Six Thinking Hats for a while now, and finally got the opportunity in a workshop last week.

I was working with a team who had a vague understanding of the roles we ought to be playing, and we wanted to clarify them. We only had a short time for the meeting, so we used the hats to help us. In an unstructured meeting, everyone will have a particular bias. Some people are very positive and look for the good in everything. Others are risk-averse. Others like to concentrate on the facts, or see the big picture. By focusing on each aspect of these in turn, we were able to give voice to everyone’s preferred bias.

As the facilitator, I took the blue hat – the big picture – and used it to introduce the agenda for the meeting, outline our objectives, and summarise what we’d learnt at each stage. Each stage was simply a brainstorm with post-it notes, which we stuck on different areas of the wall around the room.

The team started with the yellow hat, looking at the positive aspects of the problem – what our proposed solution would achieve, and what resources and people we had available or hoped to use to solve the problem.

Then we used the black hat to work out what risks might jeopardise our solution. I used the concept of a futurespective here, too, as a number of the participants confessed to having a positive bias. “It’s three years from now, and we failed. Why? What happened?”

The white hat – focused on facts – helped us look at what we knew about the problem and the solution, and what was still puzzling.

At each stage we spotted themes. I now took the blue hat again and repeated these briefly for everyone present.

We used the green hat creatively to work out what our roles should be, given the yellow, black and white hats.

As a result, we realised that up until the workshop, we had been very focused on technical detail, and not as much on the people-oriented aspects of the problem. I kept the red hat with its emotional focus in reserve in case anyone seemed unhappy, but everyone was smiling when they left, and my team-mates declared the workshop a success!

I borrowed the programme for the hats from Wikipedia, which has a great summary. We ran the meeting across virtual conferencing in three countries, using big, coloured pictures of hats to remind everyone of the focus, and to provide a visual anchor and memory aid. Dan mind-mapped the results; this also works very well with the pre-defined themes.

Next time I think real (or paper) hats may be in order…

Posted in breaking models, coaching | 5 Comments

Who’s the best person to fix this?

I hate blame cultures. If you hate them too, then you don’t need me to tell you why. If you don’t, you probably haven’t worked in one yet.

At one client, they have a strong dislike for blame cultures. Unfortunately, most of the development team have worked in one at some point or another, and it’s hard to get out of certain habits.

“Ah, it’s all right,” one developer said, looking at a bug. “It’s not our fault.”

“I’ve been learning a bit of NLP,” I said, “and it suggests that the words we use can sometimes affect the way we think. I know that you’re not really thinking about blame when you use those words. Even so, can we avoid them? Could you maybe ask the question, Who’s the best person to fix this? instead of Whose fault is it?

“All right. I’m still not the best person to fix this, though.”

“Well, who is?”

“I think George broke the build. I mean, George is the best person to fix it.” The developer called across, “George, can you look at the build a sec and see if you could fix it, please?”

“Oops!” said George. “I’m on it.”

So he fixed the build, and the team started working. A while later, one of the QAs called me over. “Liz, I’m looking at this bug… did your team cause it?”

I shook my head. “It looks like the database might be down.”

“Oh,” the QA said sadly. “I can’t blame you, then.”

I winced. “Why do you need to know whose fault it was?” I asked.

“So I know who to assign it to.”

So I explained about the new words we were trying to use instead of “blame” and “fault”.

“Oh!” she brightened up. “Well, are you able to help me fix it, then?”

“Maybe one of my team can help. Hold on!” So I asked around. “Who’s the best person to kick Mary’s database? It looks as if it’s fallen over.”

“I can do that!” Fred announced.

It occurred to me at that point that, if we were still asking, “Whose fault is this?” then Fred would be reluctant to help out, because it would insinuate that it was somehow his fault. By avoiding the words and asking, “Who’s the best person to fix this?” anyone can volunteer.

Suddenly, by providing an alternative to “fault” and “blame”, we’ve made it OK for people to volunteer to contribute. That can only be a good thing.

Posted in nlp | 7 Comments

Standing-up dragging on?

There’s a standard format for stand-ups that goes:

  • What did you do yesterday?
  • What are you going to do today?

As well as this, it helps to keep the focus on things that are interesting to the team.

Sometimes this can lead to stand-ups becoming little more than status meetings, or updates for a team leader’s benefit. So here’s something that I’ve been doing both for myself, and with teams, that seems to liven things up a bit.

  • What did you learn yesterday?
  • What do you hope to learn today?

Participants who’ve used this as well as or instead of the usual format have talked about contacts they’ve made in other teams, difficulties they’re having with particular technologies, puzzles they’re trying to solve, domain knowledge they’ve picked up or are looking for, etc.

Posted in learning | 1 Comment

Love for Pigs and Chickens

A phrase frequently used in the Scrum teams I’ve been involved in – as well as a few of the XP teams – is “Pigs and Chickens”.

Googling the origin, I found out where it came from. Like many terms and practices in Agile Software Development, it’s surrounded by controversy.

I have come to love the phrase, mostly because it causes people who are unfamiliar with Agile and Scrum practices to ask, “What are pigs and chickens?”

When the Agile team members smile and happily explain the joke, the people asking the questions often remember that they have other questions they wanted to ask, too. Then they find out that most Agile teams are full of real human beings who love to talk about what they’re doing and share good practices. This in turn invites more conversation, which spreads the goodness.

That leads to requests like, “Liz, I’d love to see what the team are doing with <xyz>. Can I turn up at your meeting, please, just as a chicken?”

Anything which facilitates better communication – even by being an obscure hook that invites curiosity – has got to be good.

Posted in scrum | 4 Comments

C# mocks in action

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.

Posted in bdd | Leave a comment

Given, when, then and examples for classes

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.

Posted in bdd | 9 Comments

The problem with Scrum

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.

Posted in learning models | 1 Comment

Dan and I talk about BDD at Oopsla 2007

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!

Posted in bdd, stories | Leave a comment

fail() failed…

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).

Posted in bdd | 2 Comments

Four ways of handling Givens

A Given is the context in which a feature is used

When we write code, we want to know that it works. As developer, I want to know how to tell this before I even start coding, so that I can do as little work as possible.

This isn’t laziness – it’s simplicity! It just happens that it also lets me head for the pub sooner (“Beer Driven Development”).

In order to know whether my code is working or not, I’ll run the same kind of manual tests as the QAs will. I’ll also try to automate these.

I start by thinking about how I’m going to use the feature I’m checking, and the outcomes that I’m expecting. That then leads me to think about the things I need to do first, before I can use my feature.

For instance, I think about successfully paying a bill through my online banking system. That reminds me that I need to have sufficient credit with the bank, either a positive balance or perhaps an overdraft facility.

We can use the application to set up a Given

I could pretend to be an admin at the bank, and use the application to create a new account. I could then deposit some money in the account. That would allow me to try and pay a bill and check that the bill payment code worked.

We can set up the state directly

Let’s suppose that all bank account and balance details are stored in a database. I could set up the data in the database to make it look like an admin had created an account. That’s OK, because it’s not the account creation functionality we’re worried about – we probably have another scenario that covers that.

We can use existing data

Let’s say that we’ve copied a production database, or that we have some test data with which all environments are initialised. Maybe I have an account for a “Mr. Test”, with £2000 in.

I could use this account for my scenario!

But what happens if someone changes the data? Suppose that someone else writes a scenario that withdraws all the money, and it runs before mine? The first I will know about it is when my outcome – that I paid a bill successfully – fails.

So, it’s useful for me to check that the state I need really does exist, either by checking the contents of the database, or by using the application to log in as Mr. Test and verify that my balance is sufficient. Either way, my Given contains assertions, just like my Then. It will fail if it can’t find the right data. This will help me differentiate between the wrong setup, and a genuine bug.

We could use state if it does exist, and create it if it doesn’t

If I wanted to, I could look to see if Mr. Test’s account existed, and if he had enough money, then create his account or add more money if he didn’t. This might be useful if, say, setting up an account was very expensive, but checking its existence and balance wasn’t. In that case, we’d have an assertion which performed the setup if it failed.

I’ve never had reason to do this. Let me know if you do!

Posted in bdd | Tagged | 2 Comments