How to focus on quality
Focus on Quality. It sounds innocent enough. Just make sure you do everything perfectly, or at least as perfectly as you are able.
If only it were as simple as that. I distinctly recall during my younger years as a developer, believing firmly that if software you wrote had bugs in it that you were aware of, you simply should continue working on it until it didn’t. This was about the time that Windows would crash on you every 20 minutes, plus or minus 30 minutes. It was increasingly frustrating to even use a computer, mainly because the system would just die, often for what was apparently no good reason.
“Why didn’t they fix this before it went out the door?!?!”
Well, either they didn’t know about it, or they didn’t care. The correct answer is neither. They simply didn’t have time.
As my career unfolded, I ran into an increasing number of managers who simply didn’t know what they were doing, and of course I knew better. “The software still has this bug in it. Why are we shipping without fixing this bug!”
Eight years later, I finally know the answer to that. If we waited until all of the bugs were fixed, the software would never be finished. There’s always something else to tweak, more functionality to add, a bit more performance that could be squeezed out of this algorithm or that one. Developers tend to be perfectionists. I think you almost have to be if you want to be a good developer. But it can be frustrating to know that your software that is going out the door still has problems, or isn’t as manageable as you’d like it to be.
The main source of these problems is really a lack of time to do the work. Adding more developers may solve short term problems, but it’s not a long term solution. It simply adds to the confusion generated when architecture changes are made, or more features are added. But there are some rather simple things that you can do to cut down on the time that you spend working on trivial stuff that you shouldn’t have to devote extra time for to begin with.
If you take steps to increase the amount of time available to you, then any time savings you create can be used to increase the quality of your product. Interestingly enough, many of these crucial time savings actions actually contribute to making a higher quality product.
1) Use source control for nearly everything, no matter how large or small your team is.
Even when working on projects all by myself, I always use source control of some kind. It’s incredibly stupid not to, but people still do it. These are the people who have never lost their work to a drive failure. Your hard drive can go at literally any time. Most of the time, you at least have a little bit of warning. With one exception, every drive failure I’ve ever had gave an audible indicator that something was going seriously wrong.
The drive would start clicking, or making strange whirring noises. That meant it was time to buy a new drive and copy everything to it ASAP. Some people use multiple computers and store copies on multiple machines. This is rather effective, but if you’re doing this, then you’re missing out on one of the key benefits of source control, which is the ability to go back to a previous version. Check in early, and check in often.
If you’re copying files all over the network, then you’re wasting disk space left and right. Disk space is cheap right? Certainly. And if it’s so cheap, then why not use a source control product that tracks the changes between versions for you? Then you can track every version you’ve ever checked in. Personally, I prefer to use SourceGear’s Vault. If you’re flying solo, then Vault is free for one user. Perforce is free for two users. And if that’s the price for you, then you always have CVS to turn to.
There are certainly other options, but source control is a must. Don’t say that I didn’t warn you.
2) Use a virgin build machine to build all of your test builds.
There will certainly be cases where you need to spin off a special build for QA to test something specific, but for your regular releases, you really need to build your product/application on a virgin build machine. ‘Virgin build machine?’ By that, I mean that your build machine should not install the product, nor should it ever. Developers sometimes install software that adds things to their Global Assemblies, or they assume that code or images they added to their local solutions have been added into source control. If the build breaks because they forgot to check something in, then it’s a sign that the process is working.
In my own environment, I have a Windows XP Professional machine that has all of the latest patches running builds. Better yet, my build machine is actually a VMWare image. So I can back it up and move it around whenever I feel like it. If a developer needs to make some tweaks to the build process, or needs some one shot customizations done, he can copy the image, tweak it, and never even touch the actual build machine. There’s no chance of hosing it. Better yet, is the fact that if anything ever happens to the computer it’s running on, you simply fire up the image on another computer. In 2 minutes, your build machine has been recreated. No hassle, no fuss.
“But, what’s the big idea of having a build machine in the first place? My computer can build the software just fine!”
Perhaps. But my build environment is a little more complicated than simply clicking Build. First, it gets all of the latest versions of everything in source control. Then it builds the applications. Next, it obfuscates the C# code. Next, comes the digital signatures, and finally the installer is fired off.
All of this is done through a single script. How many times do you think that I’ve messed up the build process? Yea, not many is right.
3) Use coding standards and make sure that everyone follows them.
This is a much bigger pill for an established development team to follow than for one that is just being formed. Most larger teams have some sort of coding standards they follow so that the code maintains at least a small level of consistency from one class to the next. It’s bad enough when you didn’t write the code, but to follow up after someone who writes really cryptic code can be an absolute nightmare.
During my career, I’ve been on my fair share of development teams where at least one person could have been labeled as “Does not play well with others.” It doesn’t mean they’re dumb. In fact, it can mean quite the opposite. At Clearwire, one of the developers we worked with was practically driven out of the company because his code simply couldn’t be read by anyone. He really was a very smart guy, and his code had a tendency to be very good. But when bugs were detected in his code, it was very nearly impossible for anyone else to track down the problem. Often, it was interoperability problems due to architecture changes.
But still, the fact remained that his code was simply too cryptic. There are a lot of tools out there which can help with this sort of thing. You can run them as part of your nightly build process. You’re doing those now, right? On your new, fancy VMWare image? Good.
Recently, I started a project to get the source code here at Moon River Software under control using FXCop. By doing so, I can make sure that all naming conventions are followed, and that all of the code at least conforms to a standard. The great thing about standards is that there are so many to choose from. And FXCop appears to allow users to customize the rules to some extent, further defining their own internal development standards. This is probably more time consuming than either of the previous two efforts, but code maintainability is very important.
4) Document everything that you can.
I’m a big fan of documentation, but notice that I said ‘everything that you can’ as opposed to simply saying ‘everything’. The fact is that occasionally, there simply isn’t time. Of course, that’s why you’re reading this. Try to make time to do documentation. This includes application documentation, internal process documentation, network documentation, etc.
Most teams I’ve worked on have had their own intranet and development server. Developers have access to create web pages with links to all sorts of things such as testing documentation, build environment requirements, setup requirements, source code documentation generated via javadoc or other documentation generators, etc. You know what works great for this sort of thing? A Wiki. Most small teams could benefit from setting up a Wiki to help the development team add documentation for various procedures and technical notes. Even full product designs can be done in a Wiki, because it’s a fairly collaborative environment. Chat boards can also work.
5) Create a functional spec for new projects and new versions.
There’s a difference between a functional spec, and a design spec. It’s a pretty basic difference. Functional specs describe how the software will work for the end user. Design specs describe the internal workings of the software and how different components interact with one another. The combination of the two will give you a solid blueprint for your software and how it needs to be put together.
6) Reuse code whenever you can.
No, this isn’t a license to copy-paste code. Quite the opposite. Anytime that code can be reused, you accomplish a number of different things all at the same time. First, you save time because you’re not rewriting the code to begin with. Second, you’re consolidating functionality so if bugs are found in the code, it will need to be fixed in fewer places. Finally, if the code has been in use previously, then theoretically it has already been tested to some degree. So, the quality should theoretically be higher.
7) Automate your testing, not to mention everything else that you possibly can.
I have to admit a little bit of prejudice here. I hate doing testing. It’s not so bad the first time, or even the second. Possibly the third. But by about the tenth time of doing something, it’s pretty much all I can do to keep from putting my head on the railroad tracks and singing as load as I can. Repetitive tasks are the most boring job ever devised. It should be the punishment for delinquint children. But these are the sort of tasks that can be automated. Quite easily in fact. There are probably a few dozen products on the market, all aimed right at allowing you to write fully automated test suites.
Many are so simple that you can click a button and tell it to record what you do for the next few minutes. Then after you click stop it will show you what keys you pressed, when you pressed them, where your mouse moved, and lets you add and delete new actions as if they were a movie sequence. Pretty slick stuff. Imagine writing the tests to test the testing software though. Just the other day I had to modify a script that was perhaps a couple thousand lines long.
I use CodeWright for most of my script editing. I got into it back in 2000, and have used it ever since. Anyway, I discovered that CodeWright has a Macro feature, where it will record keystrokes for you. I recorded holding the shift key, down 6 times, delete, down two more times, hold shift, hit down, delete, down two more times, hold shift, down 6 more times, finally delete again.
It took me perhaps 30 seconds to figure out how to use it and set it up. 200 macro runs later, I was finished. Now, I’m a very well accomplished script writer and could have easily parsed the file with a perl script, sed, awk, or something along those lines. It really wasn’t worth the time and effort. It was too much work to do manually, and too much work to write the script to do the work. But the macro was the perfect solution. The same thing goes for automated test suites. I think it would be hard to go wrong with an automated test suite. It’s amazing the things they can catch, especially if you wire it up to the end of your build process to install your product, load it with test data, use it, and then uninstall. All of this in the middle of the night when you’re not doing anything else with the machine anyway.
I wrote this article several days ago and waited to publish it because I felt that I was on the wrong track. It seemed as if I was concentrating on all kinds of things that a company should be doing that were related, but not exactly focusing on quality. After careful consideration, I realized that I was on the right track and simply didn’t realize it yet.
If you want to focus on quality and you try to do so explicitly, you’re going to fail. You can’t simply tell someone to write better code and think that it has the remote chance of happening. You also can’t decide to design your software better. That doesn’t happen either. At least not until Version 3 hits the shelves.
The simple fact is that you can’t focus directly on quality. You need to focus on everything around it. Focus on the processes surrounding the things that you want to be higher quality. Want higher quality code? Put a process in place for code reviews. Want better documentation for the software? Have your doc writer send the documentation to the developers to review for technical accuracy. Then send it to the marketing folks to see if they understand it. If both groups give their seal of approval, then your documentation is flawless.
Want a better designed product? Wait till version 3. Just kidding. Write functional and design specs. Then read them. Reread them. Make sure everyone else has read them. Read them again. Then execute.
It’s not exactly rocket science. But people have been screwing this up for years now, and the trend is very likely to continue. The fact is, people generally don’t take the time to improve processes because they don’t think they have the time available to do so. In fact, I don’t think that most people realize the benefit of having these processes in place to begin with. It’s amazing how much easier your life can be if you just change your focus a little bit.
By focusing on the processes surrounding the problems you’re encountering, you can modify the process to be better. This will in turn, provide higher quality in whatever it is that the process is controlling.