October 2010

Features != User Stories

User Stories are a great way to plan your work. You can take a big hairy requirement and break it down into chunks that are small enough to work on without anyone freaking out. When you’ve crumbled up your big hairy requirement into little user story chunks, you can pick and choose which chunk to build first, and even drop some chunks altogether when you realise they’re not that important. Great stuff.

So we like user stories. They’re our friends. Here’s one:

In order to pay for the items in my shopping cart,
As a customer,
I want a credit card checkout

Now, suppose when we do the analysis for this story we discover that certain types of credit cards are much easier to hook up to a checkout than others. We want to ship something as soon as possible, so that people can start giving us money. So we split the story in two.

One for the friendly FooCorp credit card:

In order to pay for the items in my shopping cart,
As a customer with a FooCorp credit card,
I want a credit card checkout that accepts my card

And another for the altogether-much-harder-to-integrate-with BarCorp credit card:

In order to pay for the items in my shopping cart,
As a customer with a BarCorp credit card,
I want a credit card checkout that accepts my card

As everyone knows, BarCorp have some really outdated systems, and connecting to their payment processing is a right old pain. We’ll leave that for later.

So let’s get on with implementing our first story. We’ve done some analysis on it, but let’s make sure we understand the acceptance criteria. We have a little sit-down with our product owner, and come up with this list:

  • when a user attempts to pay with a BarCorp card, we show them a “Sorry” message
  • when a user pays with a FooCorp card, we send them an email with their receipt
  • when a user attempts to pay with a FooCorp card but gets their details wrong, we bounce the page and show them an error message, so they can correct their mistake.
  • when a user attempts to pay with a FooCorp card but the card is declined, we bounce the page and show them an error message, so they can try another card.

So those are the acceptance criteria for this story. We didn’t do anything fancy with them like put them in a Microsoft Word® document or a Jira ticket. We just wrote them down on a piece of paper.

Now we’ll use Cucumber to document these acceptance criteria as Scenarios that we can use to drive out the behaviour we need to get this story done.

Let’s start by creating a new feature:

mate features/pay_with_foocorp_card.feature

Wrong

Whoops. You made a mistake. Did you spot it?

That’s right, you went and got confused and thought that the user story you were implementing now was the same thing as the feature. It’s not.

Right now, this distinction probably seems a bit nit-picky. But wait until you’ve got around to implementing BarCorp’s credit card check-out, and BazCorp’s too. Your features directory is going to look like this:

features/
  pay_with_foocorp_card.feature
  pay_with_barcorp_card.feature
  pay_with_bazcorp_card.feature

Can you see where this is going? Give it a few months, and your features directory is going to look like a history log of the development of your project. Hey, while you’re at it, why not put the jira ticket in the filename, or even use a tool to synchronise the feature files with Pivotal Tracker?

I see lots of people doing this, and trust me, it’s an anti-pattern.

Before there was Cucumber, there was the RSpec Story Runner. There was also this blog post. That was a long time ago. When Aslak created Cucumber, he renamed the files from .story to .feature. This wasn’t an accident or an idle act of whimsy: it’s because there’s a difference.

User Stories are a planning tool. They exist until they’re implemented, and then they disappear, absorbed into the code.

Cucumber features are a communication tool. They describe how the system behaves today, so that if you need to check how it works, you don’t need to read code or go punching buttons on the live system. Organising your features according to the way they were planned and implemented is a distraction from this purpose.

Imagine if the user manual for your washing machine was organised by how the washing machine had been constructed? A nonsense.

Going back to our example, let’s rename our feature:

mv features/pay_with_foocorp_card.feature features/pay_with_credit_card.feature

Now that’s more like it. As we implement the first User Story for FooCorp credit cards, we’ll put some scenarios into this feature. When we come to implement BarCorp support, we can add a couple more scenarios to the same feature. We might even have to modify existing scenarios, perhaps if we add a new widget to the UI to let the user choose their credit card type.

The User Story is absorbed into our features and becomes invisible, leaving the features as a live document of what the software does now, not as a record of how it was constructed.

Thanks to Paul Wilson for reminding me to write this post.

Agile / Lean Software Development

Comments (10)

Permalink

Seven Truths Exercise

Recently, I played a game with a team I was training which I called “Seven Truths of Test Automation”.

I got each “truth” and wrote it on an index card and put it in a (blank) envelope. I got to the training room early and hid them around the room, not very well, so that they were quite easy to find.

We did some other stuff first, and people were looking at all these little envelopes sticking out from behind whiteboards and under cushions, wondering what was going to happen.

Then I told them that we were going to play a game. I told them that there are seven truths of test automation, and they were about to discover them. I split them into 6 small groups. I then told them they would each go out and discover a truth. When they found it, they had to ask themselves the following questions:

  • Do we agree with this?
  • What are the implications of acting on this truth?
  • What are we going to do now?

I wrote those questions on a flip-chart. We then played the game out as a group on a single truth to make sure everyone got it. I made sure that we had a full and frank discussion about whether we agreed with the truth or not. We thought through the implications (good and bad) and listed them out. We then talked about some concrete steps we could take. When they offered vague intents “We’ll start getting better at reducing duplication” I urged them to say exactly what they were going to do next week to get better at reducing duplication.

Then they split off and each did their own. They wrote up a poster and we did a gallery at the end of the session where they had a chance to share their learning with the group.

It worked really well, generated great energy and used up a good couple of hours.

For the record, I think the truths I used with this group were:

  • test automation is software development (this is the one I picked to do with the whole group)*
  • duplication destroys maintainability*
  • incidental details destroy maintainability*
  • know when it’s OK to cheat
  • some things just aren’t worth testing
  • work with developers to make their systems testable
  • don’t test other people’s code

It felt a bit egotistical handing them down My Seven Truths, so I made the point that they were just my truths, and they would discover their own as they learned to become better testers. You could obviously vary the truths depending on what you think the that group needs to hear / discuss, and those truths could be about anything, not just test automation.

Agile / Lean Software Development

Comments (3)

Permalink

Installing Ruby Gems with Native Extensions on Windows

If you’re stuck trying to run Ruby on Windows, one barrier you might have encountered is in trying to install a gem like ruby-debug or rdiscount. You’ll have seen an error like this:

%gem install ruby-debug
Building native extensions.  This could take a while...
ERROR:  Error installing ruby-debug:
        ERROR: Failed to build gem native extension.
 
C:/Ruby187/bin/ruby.exe extconf.rb
creating Makefile
 
make
'make' is not recognized as an internal or external command, operable program or batch file.
 
 
Gem files will remain installed in C:/Ruby187/lib/ruby/gems/1.8/gems/linecache-0.43 for inspection.
Results logged to C:/Ruby187/lib/ruby/gems/1.8/gems/linecache-0.43/ext/gem_make.out

That’s no fun.

The good news is, the lovely guys at Ruby Installer have put together a fix, called the DevKit. This installs the low-level bits and pieces needed to build those pesky native extensions on your Windows machine. There are a couple of manual steps which I didn’t find especially clear, so I’m documenting them here.

  • Download the DevKit self-extracting archive here
  • Run the archive, and when prompted, choose to extract it to C:\DevKit
  • When the archive has finished unpacking, open a command prompt in C:\DevKit and run ruby dk.rb init ruby dk.rb install
  • That’s it. You can test it using: gem install ruby-debug

Hooray!

Ruby Programming

Comments (3)

Permalink

Photoshop Driven Development, Anyone?

This afternoon I came across a presentation by Michael Tamm on his libary Fighting Layout Bugs. This is an idea that I too, have had bubbling around in my head for some time. Michael, to his credit, has decided to actually do something about it.

Michael’s library takes screenshots of sample pages during a test run and analyses the bitmap, checking for text that’s overflowing a bounding line, for example, and highlighting it. You can even use this to fail the build!

Screen Shot 2010 10 01 at 17.31.34 Screen Shot 2010 10 01 at 17.32.01

I can see these kind of checks being really useful to HTML / CSS hackers to help catch basic mistakes, but I still would love to see a test driven approach become available to front-end coders. When we drive out code from a failing tests, we test the tests as well as the code, because we see the test fail before we see it pass. What if we could do that for our markup and CSS?

I therefore propose: Photoshop-Driven Development.

We can take a PSD design for a page, and compare the design with the rendered page. If the rendered page doesn’t match the PSD, we fail the build until it does.

Of course it could never be as simple as this. Not every pixel in the PSD needs to be in the rendered page: some of it will just be dummy text that you’d never need or want to validate. Also, while a PSD is a fixed size, the way a page behaves when it resizes is an important (and potentially buggy) piece of the puzzle.

Could there be a way to highlight the parts of a PSD that are important? Could the designer use naming conventions for their layers to indicate whether they are just dummy content to be ignored, that they’re bounding boxes that need to flex, or key content that must be there—and precisely there—at all costs?

Crazy? Possible? I know I haven’t got time to play with it right now, but maybe you have?

Agile / Lean Software Development

Comments (3)

Permalink