There’s a great line from the Bible book of Genesis where a servant to Pharaoh said, “It is my sins that I am mentioning today…” I’m going to mention one of my sins, and record what I plan to do about it in the future.
In a previous gig, one of the first things I did as project manager was to meet with the head of QA – we had a large team of about five full-time testers. He had a long laundry list of complaints, beginning with “Testing is an afterthought here.” Even though we had such a large team – nearly 16 – development raced ahead of unit and functional testing. Our unit testing was running about 6-8 weeks behind development, and our code coverage was AWFUL.
I ‘fixed’ this by integrating development and testing so we would meet together daily, by having weekly 1:1’s with QA, and sending out code coverage/unit and functional test coverage #’s as metrics in weekly status reports. I even went so far as to host a company-wide summit on testing best practices. Yet, though things improved, we still weren’t working in synch. Major regression issues would crop up on nearly a weekly basis. We had to hire an overseas team to test the application in different browsers for issues that our automated testing wasn’t catching. It still very much felt like we were working as two teams – one pulling against the other.
Of course, the issue started with me. As a developer that grew up in the era before TDD, I still viewed testing as being secondary to development – and as a “like to have”, one that often got in the way of implementation. As a result, we had two teams with implicit values – the “alpha team” of ace developers that were shoveling out code and hucking it over the fence, and the QA scrubs that were playing cleanup.
Of course, I couldn’t have been more wrong. Testing is everyone’s job, and if you’re a competent developer you need to write unit tests alongside your code. Look at the graph below:
That’s two teams from the same company working on projects of similar scale. Notice the team that implemented TDD took almost twice as long in development. But look at the lower time in handling regression and refactoring code! And which customer do you think was happier in the long run with a higher quality product being deployed the first time?
Legacy code is untested code – as Michael Feathers wrote in his great book “Working Effectively With Legacy Code“. In some projects, we’re almost leveraged into writing legacy code from the get-go due to timing demands. But that doesn’t excuse us as responsible professionals from not going back after the push and creating a robust test project.
I’m still not sure if TDD is the cure-all that some say; there may be a middle path that hits a better balance between fast development and 100% code coverage. But I do pledge to take a more in-depth look into testing, and fold TDD into my work practices.