Know what you’re building
If you set out to build something, you need to know what it is that you need to build. That’s just common sense, right?
Unfortunately a lot of companies struggle with this. It usually starts with requirements that don’t have the level of detail that they need in order to cover all of the edge cases. That leads to developers getting frustrated, guessing at the requirements, and low morale, among other things. In my opinion, this is not that difficult of a problem to solve. Here are some steps that might help:
Define the scenarios
As a developer, don’t start working on a feature until you can specify all of the testing scenarios in the Given/When/Then format.
Given I am a logged in user
When I go to the new order screen
And I try and purchase an iPhone
Then I should see a message saying that I’m eligible to buy a phone at the promotional price
And I should see a date when the phone is expected to ship
There are multiple reasons to do this. First, someone is going to have to test the feature at some point. You might as well define all of the test cases before you write the code. Otherwise you will have to guess what it is that you’re supposed to build since the QA team is going to define what “done” means. Figure out what “done” means ahead of time, and then you should have all the information you need to build the functionality with no bugs. Not only that, the QA team will be able to complete testing on your item in very little time (they’ve already written the test cases, and they won’t find a lot of bugs).
Second, do it for your own benefit. If you have Given/When/Then scenarios written out, you can easily turn that into unit tests. You can easily break the work down into smaller tasks. It also forces you to think about edge cases, design, and testing at the beginning. Now you have a good idea of what steps you need to take to build the functionality, it will be easier to write tests for everything, and you’ll know when you’re done (and how close you are to being done). You won’t get to the end and say, “I hope I thought of everything.” Sure, you might still miss something, but you’ll be a lot more confident that you didn’t.
It’s amazing how much longer it takes to develop something when you don’t have things broken down like this. It’s like you have to keep track of more things in your head, so you don’t think as fast. It’s much easier to take Given/When/Then scenarios and make them work one at a time.
Take time to design
A common misconception about Agile methodologies is that Agile does not place any importance on planning. Most Agile methodologies don’t approve of documentation for documentation’s sake. People therefore associate “design document” with “ZOMG WATERFALL RUN FOR YOUR LIVES!!!”. On my last project, my team lead had me write a design document for a feature I was going to work on and then we were going to discuss it together. The purpose of the document was not to check off a box or fill up a binder with stale technical details, the purpose was to help me think about the design. I was amazed, as I wrote everything out, I thought of all kinds of things that I hadn’t thought of before. It was an extremely valuable experience.
Agile says that we aren’t going to do big design up front, but that by no means implies that we should start working on a feature without having it defined! You may not have all of the details about what you’re going to build next week, but you definitely have to define what it is that you’re building right now. Agile does not encourage spotty requirements, in fact, it’s just the opposite. We want to have the requirements defined so that we can all agree on what the business needs and then write code with automated tests and no defects. Planning and design are not optional.
Hold your ground
If you have bad requirements, I think the buck needs to stop with the developers. The fact is that you can’t build something if you don’t know what it is that you need to build. If you know 90% of what you need to build, you can build 90% of it, but you can’t complete the feature. When this happens, you start getting a lot of bugs because no one (yourself included) thought of everything that needed to be considered.
So next time you have requirements that aren’t complete, don’t just start developing. Work with the BAs, QAs, business people, or whoever else needs to be involved to get everything defined. Once you start working on it and they see work getting done, people will assume that everything is OK when it’s not really OK. If you focus on getting all of the questions answered first, people might be more focused on getting everything defined because they’ll know that you’re blocked.
Sometimes you might have enough of the requirements that you can start developing. This is fine if you only have minor questions unanswered (“What should this error message say?”). You just don’t want to get in a situation where you’re getting stuck, you’re having to guess, or you’re having requirements changed on you because people are still thinking about the design.
Use your card wall
If you have swim lanes on your card wall, create columns for “In Analysis” and “Ready for Development” (or some similar wording). Don’t put anything in “Ready for Development” until the requirements are complete. Do the same thing in your work item tracker. We want people to be aware that there are still things to be done to define the requirements. If BAs see that, they will want to do what they need to do to get the feature out of that status and into “Ready for Development”. It also gives developers a visible way to say, “No, I need more definition before I can start developing.”
Use some tact
Please, please don’t go blasting your BAs, users, product owners, and everyone else who is not a developer. These people are trying their best (usually), but as a developer you have a different perspective on things. Your perspective is important, but so is theirs. Quit treating your users like “stupid users” and try to understand where they’re coming from, and help them understand where you’re coming from.
I’ve written plenty of requirements and it doesn’t feel good when a developer mocks the requirements that I just spent the last two days defining. Sure, I missed stuff. But no one appreciates getting put down when they’re working hard. Work with them to fix the problem, but use plenty of tact.
Be a coach
Writing code might be your primary job function, but you can also be unofficial coaches and help the rest of your team define good requirements in a way that will enable you to succeed. It’s in everyone’s best interest (yours included) if you try to collaborate more with people on your team. We like things in Given/When/Then format because we can easily write code against deterministic scenarios like this. It’s good for us if we have the test cases defined up front because it helps us know what to build. So if we can teach BAs how to write requirements this way and we can teach QAs to work with us to help define test cases before we write code, then everyone will win.
To truly be agile you need to have “just enough” requirements and design so that you have a reasonable level of certainty that you can complete a project to the needs of the customer in the constraints of the project.
Why people think that design is unnecessary or gets in the way is beyond me. Design is a good thing. What is not a good thing is the perception that “Design = 100% complete specification”. Rarely will you know 100%. On the other side, if you don’t even know 80% of the requirements, there could be a huge gotcha that’s going to derail the project and at usually when you are not aware (like a week after deployment).
I would strive for 90-95% of the necessary understanding of requirements and design synthesis. If you don’t have a high enough degree of certainty, you are carrying unnecessary requirements risk. Anything more than that percentage and you get into a law of diminishing returns and I believe you might actually detriment the project for making a premature decision.
I’m a junior dev, and don’t currently work in a place that can/will do development like this. It’s a bit disheartening, but do you have advice for how I can learn how to do this on my own? I just ordered The RSpec Book for learning BDD. Will that be a good starting point?
I like the idea of the Given/When/Then format, but I’m wondering how you ensure it’s adequately deconstructed. It seems like it’d be fairly easy, especially in the “Given” part, to have the kitchen sink. Do you have heuristics for how that should work (i.e. a maximum number of ands in the clause)? If there is too much, do you then create a more general/vague truth?
There’s no hard and fast rule for how many “ands” you can have and that sort of thing. I just to try explain things in business terms. Remember, you can have “Given” steps that under the covers might execute a bunch of little steps. So I might say “Given an active account”, when in reality, the “Given an active account” step goes and goes through a myriad of steps to create an active account.
Remember that the Given/When/Then is a common language used by BAs, developers, QAs, and the business so that everyone can be on the same page about what is being built. So make sure that you’re writing it in a way that it makes sense to all of them (particularly the business people). There are many right ways to do it, so just do what makes sense to you and over time you’ll find ways to improve how you word it.