Recently I finished a large project. No, “large” isn’t the word. Mammoth.
As far as the number of lines of new code written goes, it wasn’t that big. I only added three new source files. But the impact of the new features required subtly re-engineering hundreds of small sections of code in 45 source files in four languages. Some of this code is over 15 years old, and has been evolving fairly steadily for that whole interval. The changes were so pervasive that there was no way we could release it in phases. I don’t think that anybody would have been able to pull it off without the kind of intimate knowledge of the code in question that I possess. Still I worry that any one of those hundreds of modifications might turn into a bug factory.
Why would my client and I agree to plunge into that kind of project? Why consume a ton of hours to risk the stability of a thriving product?
Customers wanted the central feature so badly that they were already hacking it in, with limited success. The resulting unanticipated software interactions increased the number of support calls. One of the chief hackers was none other than yours truly, which brings me to my next point.
I had already created a pretty good prototype. It was about an 80% solution. More importantly, it identified areas that would need to be addressed in a full implementation, because a lot of users adopted it. The prototype only took me a day or so to whip up, but it revealed to-do’s that would consume months of development. Thus,
We knew the scope of the project going in. OK, even so we underestimated the time requirements. But that underestimation would have been an order of magnitude off without doing the research and laying out the requirements up front.
Users were involved from the start. We asked them to help us develop and review the requirements. We looked at their use of my prototype and other existing hacks to make sure we could answer the problems they were trying to solve.
We have a strong set of tests for existing features. We felt confident that we could avoid introducing bugs into users’ applications when we released the product, even if the schedule might have to expand to fix them first. Naturally, we also developed new tests for the new features, based on the requirements. Most of those tests were developed just ahead of the implementation, so my new code was being tested before the ink was dry. That allowed me to fix problems while the design was still fresh in my head.
Documentation was authored simultaneously with development. That raised a number of questions along the way that helped us identify inconsistencies and potential problems.
Long beta test, with quick updates to the beta testers as needed. No matter how many and varied your QA tests may be, your users will find their own unique ways of using the product. And Murphy says that if you break something, it will be the one thing they use every day. So you want to find that out long before release date.
That’s where it sits now, in beta. So far, I’m not being flooded with bug reports, and my client seems happy with the result. A mammoth project isn’t necessarily doomed to extinction.
Knock on wool.