Software Quality Assurance

A high-quality software application makes its users happy. They enjoy using it and it doesn't get in their ways. It yields the right results quickly, without requiring workarounds for bugs, does not crash or hogs the system, and allows the users to go on with the rest of their lives. Either the program is invisible to them and they don't think about using it, or it works so well that they enjoy using it and possibly comment about it to their friends.

On the other hand, a software application of poor quality annoys, irritates and/or frustrates its users, or even causes them to lose a lot of time, money or worse. Either it is too slow and they lose patience waiting for it to perform its function. Or it crashes a lot or hogs the system. Or it could look ugly, or have a poorly designed user-interface. Or it has other bugs like those causing data loss. Whatever its faults are, it fails or partially fails to be a useful tool in the hand of the user.

As software developers, it is our mission to make sure the software we produce is high-quality so it will perform its function properly without inflicting anguish or loss upon the user.

Now we can ask two questions:


 * 1) What makes software high-quality?
 * 2) How to make sure our software is indeed of high quality?

The answer to the first question is more straightforward: the Wikipedia has an article about Software quality, and Shlomi Fish has written an essay titled "What Makes Software High-Quality?" enumerating many of the aspects of good software applications. Most end-users can tell if a program is high-quality by working with it and testifying what they think of it (though naturally, different people may uncover different aspects of what makes or does not make the software work for them.).

Once we got that question out of our way, we can now focus on the second question: how can we make sure our software is high-quality. This will be the subject of this book. This question or the various aspects of it have been the subject of countless of books, papers, articles, blog posts and others writing. In this book, we will attempt to cover all the bases and give the various opinions on each aspect of the various proposed methods to achieve high-quality programs. After all, ask two software developers about some aspect of software engineering and you'll get three different answers.

Reuse Existing Efforts
The first rule of writing a good program is "Don't write it yet.". Instead, look for an existing effort that accomplishes all or most of what you want to do, and make use of it. The tendency of software shops to re-implement existing software poorly has been nicknamed the "Not Invented Here" syndrome (or NIH for short). If you can reuse existing code to do what you want, then you will finish much more quickly.

An existing effort may not always be suitable for use due to pricing, licensing, legal or other aspects. For example, many open-source projects have re-implemented proprietary software: OpenSSH was an open-source implementation of the SSH protocol's client and server which already had a proprietary implementation; GNU Octave is a clean-room implementation of the proprietary Matlab; the KDE and GNOME desktops (and later XFCE) aimed to provide open-source alternatives to the proprietary CDE desktop ; and so on. The developers of GnuTLS had to start a clean-room re-implementations of OpenSSL because OpenSSL had a problematic (but still open source) licence which is not compatible with the GPL licence favoured by the GNU project. And this goes on.

Sometimes a given software package may be too buggy to salvage, may not match the target platform (operating system, programming language, processor architecture, virtual machine, etc.) and as a result may be quicker to re-implement. Despite all that, one can usually find something close enough to serve as the basis for the task they need to solve and can re-use this code.

Against Code Reuse
Joel Spolsky wrote in his "Joel on Software" site an essay titled In Defense of the Not-Invented-Here Syndrome in which he concludes by saying "If it's a core business function -- do it yourself, no matter what.".

How to find reusable code
Some good sources for finding already-written software include, but note that a large amount of this code may be licensed under licences, such as the GNU General Public License that are incompatible with some use by "shrinkwrap" non-open-source software (so called "proprietary software")


 * 1) Software directories such as Freshmeat or the Free Software Foundation's Free Software Directory
 * 2) Open Source Software Development Hubs ("Forges") such as SourceForge.
 * 3) Generic web search engines such as Google search.
 * 4) The package repositories of various Linux distributions, and other distributions or operating systems.
 * 5) Collections of packages for various languages or platforms such as the Perl programming language's CPAN (the "Comprehensive Perl Archive Network").

Normally searching using a good search engine (by trying several keywords) and on Freshmeat would be enough. If you still want to be sure, you can try asking whether anyone can point you to such a program in a relevant channel in a popular Internet Relay Chat (IRC) network such as Freenode or different kinds of Internet forums.

Writing Functional Specifications
Functional specifications are design documents that aim to explain how the end-user will interact with the program, and how the program will respond. Joel Spolsky has a 4-part series on his Joel on Software site about writing functional specifications, where he has given the why's and how's of writing functional specifications. In addition, one can find the following open-content functional specifications for some open source projects:


 * 1) Functional Spec for a Freelancers Board (with a Biblical theme).
 * 2) Functional Spec for a better classification of CPAN Modules (with a theme of FOSS world  celebrities).
 * 3) Functional Spec for a Windows package management system (featuring characters from Ozy and Millie).

Opinions Against Functional Specifications
Some people believe that the time it takes to write and prepare a functional specification is better spent writing code (for their defense, one should note that writing them is much less time consuming than writing other design documents such as comprehensive technical specifications). In the context of open-source software, functional specifications may not agree with the recommendations of The Cathedral and the Bazaar series in which Eric S. Raymond claims that a programmer should work on a limited working version on his own before they can start developing it in a Bazaar style.

Code Design
Code design is an initial mental effort done to plan the way the code will evolve into the future. There are many ways to do design: by writing technical specifications (possibly not very comprehensive), by writing documentation before code, by doing design meetings with the team, by thinking, by writing notes, by preparing diagrams, etc. Most software developers when confronted with the question, will agree that it is a good idea to design code well before writing it, as fixing badly designed code may be much more costly in time.

Some schools of software engineering (such as Extreme Programming) note that regardless of how much design is handed to the actual programmer, he or she will still need to do a minimal amount of design themselves, such as deciding how to structure the internals of subroutines, or how to name a temporary variable.

Opposing views on how to design
The Extreme Programming methodology tends to look down on doing a "Big Design Upfront", where the application is designed down to minute details, claiming it will likely prove to be wrong at implementation time, will likely waste a lot of time, and will tend to make the underling programmers feel like they are being patronised. Instead it advocates a weekly design meeting where the future directions of the code are decided upon.

TODO: Add more.

Refactoring code and rewriting it
Refactoring is the process of improving the internal quality of the code (or its elegance) without changing its external behaviour. As understood from the "Refactoring" book by Martin Fowler (and from previous experience of people with "cleaning up" code), refactoring can be done by applying several well-understood transformations to the existing codebase, while preserving its integrity at every point, requiring very little effort and with relatively little risk of breaking the code.

In addition to refactoring, some programmers sometimes feel the need to rewrite portions of the code, which they deem as either completely inelegant or alternatively not fulfilling the tasks needed by the code's new functionality. An extreme form of such rewriting is starting the project entirely from scratch in what became known as a complete rewrite.

TODO: add Joel's "Things you Should Never Do, Part I", and "Rub a dub dub", the discussion about rewriting in the ack-users mailing list.