by Chris Edwards
At his previous job, Sean was a product owner in a group that had an unyielding focus on technical practices. He would tell stories of team leads honing the CI builds to get the compile times as low as possible. He brought along new concepts like Domain-Driven Design, and he had seen first-hand the benefits of Test-Driven Development (TDD).
We weren’t strangers to automated testing. We had an extensive complement of UI tests. We had invested a lot of time building our test suite and were proud of the value it brought us.
Sean gathered some data to challenge this:
- The number of automated test cases was steadily increasing
- Defect and crash injection rates were not improving
- At our current pace, it would take 2.5 years to automate the backlog of test cases
- QA spent 50%-75% of their time maintaining the existing tests
Some actual charts he used to illustrate his point:
He told us there was a better way with TDD:
- Better designs and cleaner code
- Fewer and faster detection of bugs
- The satisfaction of fearless refactoring
Sean’s enthusiasm for TDD hooked a few of us. We just got it. What I would discover is that this feeling was not universal.
I can understand people’s resistance to TDD. It is hard to learn. It was made harder by the fact that we didn’t have any resident experts and people struggled to find online resources that went beyond teaching the basics. Even those who were excited found the learning curve daunting.
There is something important I should note. At this time we were drinking from the firehose. IHS had just acquired us, we were adopting Agile, we were learning about SOLID & design patterns, and we were in the middle of rearchitecting our application. I believe we had maxed out how much change people could accommodate.
Then we made the single worst mistake we could have made. We mandated TDD.
We meant well. Trust me.
Our logic went something like this: TDD is hard. Really. Hard. People just haven’t given it enough time.
Oh, how wrong we were.
Sean created a hands-on workshop to get people started with TDD. It got people acquainted with the basic mechanics and helped them start thinking in a test-driven way.
The training only took us so far. It was perfect for greenfield code, but once we tried to add tests to any existing code, we got stuck. We were not equipped with the skills to refactor our code to be testable.
Our hope was that after people got up the learning curve that it would be impossible for them to ignore the benefits. Woody Zuill likens it to learning an instrument. You can’t just give up after you’ve gone three days without mastering it.
The more experienced devs had seen fads come and go. To them, this was just another. The excitement around TDD was unfounded dogma. They challenged the ideas with reasoned arguments. The passionate advocates viewed them as stubborn and unwilling to try new things. They responded with more intense enthusiasm for TDD. I was guilty of this as well. Without someone who could speak about the benefits from the experience, it looks like we were all drinking the Kool-Aid.
On one team a religious war began brewing. A pair of young devs were clashing with a pair of more seasoned devs. The conversations around TDD were less than constructive.
We tried to temper the debate by forming a TDD community where people could come and discuss the challenges they were seeing and share what they’ve learned. The discussions often devolved into arguments and it felt a bit like the blind leading the blind.
Where We Are Today
I’m elated to say that the chief agile transformation stuck. I attribute this largely to the experienced guidance of our Agile Coach, Sean. When we were frustrated, he was there to provide advice. When we were ready to give up, he told reassuring stories to keep us on track.
TDD, on the other hand, never reached 100% adoption. Some groups do it exclusively, and others will write unit tests when the feel it is right. Despite the mandate, some people never even gave TDD a try.
If We Had a Time Machine
“If you have a test suite that you trust so much that you are willing to deploy the system based solely on those tests passing; and if that test suite can be executed in seconds, or minutes, then you can quickly and easily clean the code without fear.”
I would also focus more on enabling the enthusiasts and less on trying to win over the opposition. We can learn from the marketing concept known as the Diffusion of Innovations.
Our Innovators are people who just got TDD. They are going to try it as soon as they hear about it. The Early Adopters are devs who just need an extra push. Words of encouragement from senior leadership that it is a risk worth taking would be enough to get them to try.
The Early Majority will adopt TDD once it has been proven successful. Due to the learning curve, or primary challenge should now be to help people get over the hump as fast as possible.
To do this, I would hire someone with extensive experience with both TDD and refactoring. I would embed them in the teams to help people hands-on. When people get frustrated, they could speak from experience about the benefits and tell stories to give them hope about how it will get better.
I would also advocating starting small and building up skills before advancing. Going to the extreme and saying that we should “TDD everything” can create a sink or swim feeling. Start small. Learn. Try something more challenging. Repeat.
I believe that if we had taken this approach the skeptics would have gotten on board eventually, and once the majority of people are practicing TDD, then mandating it to the “Laggards” is much easier.
Chris and Sean are Agile Experts based out of Calgary. For more info go here.
A quick thank you to Renee Hemsing, Krystina Edwards, Aaron Hilger and Meg Ward for their feedback while writing this article.