Saturday, September 07, 2013

Qualities of software

What are the qualities of software? When it comes to programming, there are may schools of thought.

I feel like all the qualities of software can be broken down into three categories.

  1. correct
  2. maintainable
  3. performant


This concern answers the question, "Does the code actually solve the problem it was intended to?". It also deals with the resilience of the code. Will it crash as soon as it received unexpected input, or are there flaws that could lead to security issues? Testing (from unit testing to end-to-end testing) is usually able to evaluate this quality pretty well. Code that does not have excellent test coverage (both of it's individual units, and all the components together), can't be reliably said to be correct. Beta testing, open sourcing, and exposure to more users can also help to improve the correctness of software.


Lots of code starts out (relatively) correct, but slowly over time, as features are added and bugs are fixed, becomes less correct and less maintainable. Maintainability deals with how easily code can change, and how easy it is for someone new to start being productive with the code. Code that is well structured is easier to work with, and units of code (classes, functions and modules) that have a single clear concern are easier to understand and re-use. Unit testing (especially when the tests are used to guide the code, as in TDD) is a great way to identify maintainability issues. When a unit is difficult to test, it is probably not maintainable. Documentation can be helpful, but can also be a crutch. Documentation can diverge from the actual source and become misleading, which ends up making the code less maintainable. Inline comments that don't serve as API documentation are usually a sign that code is not inherently clear. Code should be naturally readable, and only require documents as a high level guide through the different components. Code is the single source of truth (documentation is secondary), so it should be treated as such.

When code is maintainable, changes are easy to make. When code is poorly structured, it is not maintainable, and requires a lot of effort for even a minimal change.


Once correctness and maintainability have been satisfied, there is occasionally a third concern, performance. Performance deals with how well a piece of code will scale. When a piece of code is first written, it is usually only run with a minimal set of data, or a small number of users. Over time, if the code is successful, the data it operates on, and the number of users will grow. If code is performant, it will be able to handle this increase in load in a near linear increase in resource usage.

Understanding the performance characteristics of the data structures and persistence mechanisms used by the code can help guide the design of software. Doing some initial design is always a good idea, but optimization can be a never-ending process, and shouldn't start until there is a real need for it.

Load testing is a great way to understand the performance of a piece of code. By testing it with large datasets, or many automated users, you can gain a solid understanding of when a piece of code will need to be optimized or re-designed for a larger scale.


In the end, testing code is the only way to achieve high quality software; unit testing for maintainability and correctness of the unit, end-to-end testing for the correctness of the software as a whole, and load testing to verify performance. Software is always changing, and it's quality should be evaluated after every change. Automated testing is essential to that process.

No comments:

Post a Comment