The GOV.UK Pay team had some issues with delivery which were affecting the team and its roadmap. During a short space of time, we had some big partners come on board and they needed lots of new functionality. As team leads we knew we had to take a look at how to make sure we could meet tight deadlines and deliver all the features expected.
Identifying workflow problems
At our quarterly retro the team found:
- user stories were not always clear enough and could not always picked up by people who did not have context
- daily standups were not enough to communicate the complexity of the things we were working on
- not all identified user needs were being met
- projects were being reworked before being finished
- delivery was not as quick as we wanted
The root of the problem seemed to be stories which left too much room for interpretation. We committed to doing more upfront analysis, running story breakdown sessions, and creating smaller stories with clearly defined tasks and acceptance criteria. Our aim was to make sure that everyone working on a feature understood what was required, so they had the context to try and avoid surprise unknowns coming up.
Writing better user stories and criteria
Getting the stories right at the start of our sprints was one of the biggest issues we had to overcome. Without properly defined stories and criteria:
- it was hard to estimate how long stories would take to complete
- there was no guarantee that what was delivered would be what was required
- precise sprint planning was a difficult, if not impossible, task
- team members struggled to deliver a sprint goal
Here’s an example of bad acceptance criteria
A service can send a "language" property with a supported language code (English or Welsh) when creating a payment to have the payment created in that language.
To the untrained eye this probably looks like passable acceptance criteria. However, it still leaves lots of unanswered questions as we do not know what:
- language codes are supported
- formats are supported for the language codes
- the error message is for an unsupported language code
- happens if a service does not send a language code at all
Here’s an example of good acceptance criteria
Scenario 1: Create a payment in Welsh
Given a service is sending a create payment request
When the request contains “language”: “cy”
Then the payment is created in the database with its language set to Welsh
And the standard payment created response is returned
Scenario 2: Creating a payment without a language defaults to English
Given a service is sending a create payment request
When the request contains no “language” property
Then the payment is created in the database with its language set to English
And the standard payment created response is returned
Scenario 3: Create a payment with an unsupported language code returns an error
Given a service is sending a create payment request
When the request contains “language”: “cym”
Then the payment is not created in the database
And a 422 response is returned
And the body contains the error message "Invalid attribute value: language. Must be \"en\" or \"cy\""
The product manager had previously learned the Behaviour Driven Development (BDD) approach when working at DWP, and suggested trying this approach to improve the team’s collaboration. BDD focuses on using concrete examples to illustrate different scenarios in a user story. The product manager and tech lead worked together to embed this approach with the team.
We dedicated more time to writing epics and stories together as a team to help breakdown tasks more efficiently.
Using BDD helped us to write better stories as this approach:
- made it easier to spot scenarios we had not previously identified
- forced us to answer difficult questions early on rather than leaving decisions to midway through development and breaking developer flow
- made projects more inclusive as everyone in the team had a chance to contribute to decision-making
- make stories clearer as BDD forced us to write in plain English
- quickly showed if stories were too large and needed breaking down
- acceptance criteria act as concrete test cases, allowing us to verify that we’d built the right thing
Delivering our work faster with BDD
The desire to just get on with coding can be tempting, and BDD requires teams to spend time on collaborating and reviewing acceptance criteria before coding begins. We found it was worthwhile spending this time writing user stories upfront as we did not have to go back and rewrite the stories.
Once the stories are fully articulated, we're able to give robust point estimates. Because we work in sprints, we know how many points a team is likely to be able to do.
We’ve found our new approach has helped us:
- to make it clearer the team is delivering what is needed
- save time by not discussing the same topic repeatedly
- better prepare to reduce production issues, which are more costly to fix than time spent on preparation
- create more realistic delivery estimates, which has motivated the team
- let developers to focus on how they are delivering, rather than stopping midway through a sprint to reconsider what they are developing
We’d go so far to say that BDD has helped transform the Pay team. This approach has improved communication in our multidisciplinary team, which is the foundation of getting anything right. Using BDD has helped us to properly use Scrum sprints, which has given us a sense of rhythm and delivery focus.
Of course, BDD is not a silver bullet for all projects, but we highly recommend trying it out, particularly when rolling out larger features.
Let us know about your experiences of BDD and how you have overcome delivery issues.