I’m a software developer, I write software systems, big and small. I like to make things that work well, that are seen to be good. I want the software I write to be of good quality. I’m sure that any other software devs among you will agree, and those that use software would want the same out of your developers….
This seems on the surface to be a worthy goal. A good ambition for writing software; if you take the above as is, however, it isn’t.
Without much more thought about it’s implications, it’s a recipe for evangelistic wars about testing tools, testing levels; frameworks, architecture patterns and so many other things.
Now, you may have figured out from the title of this where I’m going. The above declaration has a bit of a problem, what is the definition of quality software?
This is something that all of us have come across, but is often only discussed at the low level. JMock versus Mockito; TDD versus BDD; code comments versus documentation.
All these are valid discussions, but they become evangelistic when removed from their context. If I were to write an article on code commenting versus self documenting code (for the sake of argument), I would necessarily be quite abstract about the different advantages each has. Why each is good or bad etc. Given no context, the majority would probably side with self documenting code as being of good quality, and commented code as being of bad quality, and they may well be right.
However, until you take this idea and drop it into a codebase; you can’t know what will work and what will not. Context is the final arbiter of what is good in that particular case.
This leads to an interesting thought. If we can’t discuss something as apparently clear cut as comments versus self documenting code without reference to the actual system we’re going to be putting it it, the context of the problem; software quality is intimately tied up to it’s context.
This means that we can’t come up with on overarching theory of what software quality is!
We can’t create a pithy phrase, define a set of tools or create a prescribed code style that the world will follow.
Bugger!
…
At this point, I’m going to take a leaf from other practices in the world. In other spheres, quality is not defined by the how something is done (as all the examples above are), but by the end product in it’s context. How the end product matches up to it’s requirements is the measure of quality.
Applied to software, what would that look like?
Let’s imagine a fictional product, a messaging system (because I like them!)
The business requirements would look something like :-
- Process 500 messages a minute.
- Full audit
- Store messages for 30 days.
- 99.9% uptime.
- …
These are the explicit requirements. There would be some implicit ones (commonly seen as expectations) that go with it as well, and are often overlooked in planning. For example
- It should be quick to add new features.
- Smaller team is better for the budget.
- Functionality regressions must be avoided at all costs
- …
They will change on the environment, but there are always the 2 sets.
Now, taking the above idea, that we can measure the quality our messaging app by testing it against its requirements, both implicit and explicit.
Anything we can do to meet those requirements will improve the quality of the software, as seen by the business, and by the developers. ‘Quick to add new features’ may lead us to develop a highly modular system that is enjoyable to code, or a test driven approach; ‘Avoid regressions’ may lead us to implement complete set of regression tests. All good things.
Given the context of this system, we can begin to piece together tools, techniques and technology that will meet all the requirements. It gives us an analysis tool that helps us to choose what will help us create quality software; because we have a common understanding of what is meant by that.
It allows us to be pragmatic in our choices, without resorting to simplistic generalisations on which tool/ technique/ whatever is best.
It does lead in interesting, and I think valid directions, however.
Take the requirement above – ‘It should be quick to add new features’. This can have several implications, only some of which impact the code itself. If the code were being implemented in an agile environment, you’d be able to schedule work into the flow very easily; and have it completed quickly. Similarly, a very junior team working on an old codebase will take longer to add new features, an experienced team will be much quicker. If you make efforts to spread knowledge widely around a team then you’ll see your features being implemented more rapidly.
So, the software becomes a higher quality piece, when tested against it’s requirements, only by changing the team developing it; the software itself hasn’t changed. This is weird… but an expected outworking of my assertion that software quality is intimately tied up with it’s context.
So, is software quality fact or fiction? Is there one true way to write code that is ‘good quality’?
I would say no. There isn’t. Software Quality when applied to the whole field of software development is a Unicorn, a creature that can’t be caught or tamed; and ultimately, doesn’t even exist…
Viewed pragmatically however, we are asking the wrong question.
Given my circumstances, given my team, given my code base as it is now; given my requirements, what would a quality piece of software look like? This is a powerful tool for evaluating all the tools, techniques and development methods that can help you on the way.
So the question becomes. What would quality look like in the FooBar Messaging App V1.2?
That’s real, and it’ll help tame the evangelists among us too!