I worked with a difficult client who was reporting many bugs. He led me to discover ATDD.
Hundreds of emails. Many bugs reports. Constant changes. This is a story from my days as a Senior Developer and how I discovered ATDD (before I even knew what it was).
📅 Join me at the FREE live event Stop Breaking Production: ATDD in Legacy Code (Sep 17 at 5:00 PM CET)
Endless emails and “This is wrong”
I was working with a client, it involved complex business logic and a huge decision tree.
There were a lot of meetings, a lot of emails - hundreds of emails - between the client and me.
I would develop a feature, they would test it, and say it’s wrong.
But I remembered that the way I did it was what we had agreed upon, I went back through my emails.
Then the client escalated to my boss and complained: why is the project over budget by double, triple? Why are there so many bugs?
Constantly changing requirements
I’m thinking: there are so many bugs because every day we’re emailing each other and they’re constantly changing requirements. You build something and he said what they wanted was something completely different. I got really frustrated and decided I wasn’t going to do anything without a specification - with examples, i.e., test cases with inputs and outputs.
At that point I didn’t know about ATDD or any of these approaches, but I realised this is where we were disagreeing. These test cases forced me to think about variations, and concrete inputs and outputs. Later they couldn’t say it’s supposed to be a different number or color based on the logic.
Requirement alignment first, coding second
I got the client to confirm the test cases before I began development. For some test cases, they would immediately say, “Yes, this is right.” For some others, they would say, “No, this is not the expected output,” and then they would tell me the correct one. For other cases, they’d say, “I didn’t think about that case, I’d have to get back to you.” And in some test cases, I’d ask, “For this scenario, what should happen? What should be the output?” and they would say, “I didn’t think about that case.”
This actually led to corrections in the test cases before I began development. When I did the development, I just checked: did I meet those outputs? Later, during testing, they couldn’t tell me the output was something else. There were a few cases where they said, “That’s not expected behavior,” and I pointed to where we had agreed and written it down, and then they’d say, “Oh, okay.”
They couldn’t raise it as a bug; only a change request was possible.
It was the first project where I didn’t receive bug reports during UAT!
Automate to save time
The other thing I also did was automate those tests, because I realised it was too time-consuming for me to execute them manually. There were so many scenarios, and it was boring for me to check them. I automated them even through the UI.
What’s the lesson?
Basically, think of test cases before you start development, not after. I learnt this lesson thanks to the difficult client I had to work with (back in the time when I was working as a senior developer).
I later learned that this approach (of writing example-based requirements before coding) is called ATDD.
Want to apply ATDD in practice?
You tried ATDD, but it didn’t work. That's why I'm going to help you practice ATDD step-by-step. Apply ATDD on a sandbox project. Access TDD in Legacy Code.
Should every requirement include concrete inputs and outputs?