Software Quality
Jakob Jenkov |
When we talk about software quality we are usually referring to very specific software quality factors. To improve software quality overall, you will typically improve the software along one or more of these software quality factors. In this software quality tutorial I will list and discuss the most common software quality factors that we developers should be aware of. This list is not 100% exhaustive. Your particular software might have have some unique quality factors.
Why Software Quality Matters
To be able to sell your software to customers, you must be able to sell it at a price where the the software is worth more to the customer than they pay for it. Software quality has an impact on both of these aspects - both how valuable your software is to its customers and users, as well as on what it will cost to develop and operate - and thereby what price you can sell it for.
Software quality also impacts evolution speed as the software's code base grows. You can often get away with lower quality in structure, design and testing in the beginning of a project when the code base is small, but as the code base grows, it gets harder and harder to navigate the code base and make changes to it, if the code quality is low.
Software quality is not the only thing that matters, though. Time to market, timing of market, marketing systems and campaigns etc. matter a lot too. Software design matters too. Some designs can serve the same number of customers on 1/5 to 1/10 of the hardware that other designs use.
Software Quality Factors
I have listed the most common software quality factors below. Over time I will add some explanation to each of these factors in subsequent sections.
- Correctness
- Testability
- Test Requirement Coverage
- Test Code Coverage
- Usability
- Solve the user's problems
- Require minimum effort from the user
- Minimal thinking
- Minimal physical work
- Don't create any new problems
- Operability
- Installation / upgrade / deployment
- Start / Restart
- Shutdown
- Removal / Uninstall
- Configuration
- Resource utilization monitoring
- Log monitoring
- Health monitoring
- Evolvability
- Readability
- Extendability
- Reusability
- Composability
- Resource Utilization Optimization
- CPU Utilization
- Memory Utilization
- Disk Utilization
- Network Utilization
- Security
Correctness
Software correctness refers to how easy it is to verify that the software behaves correctly, meaning behaves as specified. I have divided verifiability into a set of subcategories which I explain in the following sections.
Testability
By testability I mean how easy is it to test the software against the requirement specification? Or - how quickly will errors be found during regular use after deployment? This is not an ideal way of testing, but many errors are found this way in reality (unfortunately).
When improving testability you will typically realign the code design to make it easier to write unit tests and integration tests for the software.
Test Requirement Coverage
By test requirement coverage I mean how much of the requirement specification is covered by the tests. The higher percentage, the better.
Code Test Coverage
By code test coverage I mean how much of the code base that is covered by the unit tests and integration tests. The higher percentage the better - but the last 5-10% can get quite expensive to reach.
Usability
By usability I mean how easy the software is to use for the end user. If the software is an API or toolkit, usability refers to how easy that API or toolkit is to use for the developers integrating with it. I have divided usability into three more concrete goals which I explain in the following sections.
Solve the User's Problem
The first and most important usability factor is of course to solve the user's problem. If your app, API or toolkit does not solve the user's problem, or only solves it partially, that decreases the usability of your software.
Require Minimal Effort From the User
The second most important usability factor is how easy your software is to use. By easy I mean how little effort the user has to invest in learning how to use your software as well as actually using it. In other words, both mental and physical effort. The less effort is required, the better.
Don't Create New Problems
The third usability factor is to not create new problems for the user. Some software solves one set of problems but creates another set of problems. This is really annoying for the users - and this decreases the usability perception of your software. Try not to create new problems for the user.
Operability
By operability I mean how easy the software is to operate during and after installation. Operations tasks are also sometimes referred to as administration tasks. I have subdivided operability into a set of subfactors which I have explained below.
Installation / Upgrade / Deployment
By installation, upgrade and deployment is meant how easy it is to deploy your software, e.g. install or upgrade it. The easier, the better.
Start / Restart
By start I mean how easy it is to startup your software in an operable state when the software is not yet running. By restart I mean how easy it is to restart your software when it is already running - in case a restart is desired.
Shutdown
By shutdown I mean how easy it is to correctly shutdown your software once it is running. The easier it is to shutdown your software correctly, the better.
Removal / Uninstall
By removal / uninstall I mean how easy it is to remove or uninstall your software after a successful (or unsuccessful installation). The easier, the better.
Configuration
By configuration I mean how easy it is to configure your software correctly. The easier it is to configure, the better. You can make configuration easier by having your software use sensible default configuration values, so you only need to change the configuration if you are not satisfied with the default settings.
Resource Utilization Monitoring
The resource utilization monitoring factor refers to how easy it is to monitor how well the software utilizes the resources of the hardware it is running on. This typically consists of monitoring CPU, RAM, disk, network and IO utilization. The easier it is to monitor resource utilization, the better.
Note: In some setups resource utilization is monitored by the underlying OS or runtime platform such as a cloud platform.
Log Monitoring
By log monitoring I mean how easy it is to monitor the log of your software for information, warnings and errors. The easier the better.
Health Monitoring
By health monitoring I mean how easy it is to monitor if the software or system as a whole is healthy. In case of a distributed system, how easy is it to monitor the health (running state) all the nodes in the system.
Evolvability
By the software quality factor evolvability I mean how easy it is to evolve the software. In other words, how easy it is to develop future versions of the software. The easier it is to evolve the software, the better. I have divided evolvability into a set of subcategories which I will explain in the following sections.
Readability
By readability I mean how easy it is to read the code. By "read the code" I mean "understand the domain logic behind the code". Everyone can read the code and see what it does, line by line. It is a lot harder to understand why it does what it does. The why is what I refer to with the term "domain logic".
Writing code that clearly conveys the domain logic, the "why", is not easy. It typically requires splitting the "how" from the "why" - by naming variables and functions after what they do domain-wise, not code-wise.
Extendability
By extendability I mean how easy it is to extend the software by addding new components that "plug into" the existing code, without having to rewrite any of the existing code.
Reusability
By reusability I mean how easy the existing components are to reuse in future evolutions of the software. The easier it is to reuse the existing components, the easier it becomes to extend the code without having to change any of the existing code. Thus, reusability helps with extendability.
Composability
By composability I mean how easy it is to compose your domain logic from smaller components. Composability requires a special kind of reusability and extendability which I refer to dynamic composability. I will explain that in its own tutorial one day.
Resource Utilization Optimization
The better your software utilizes the resources it has at its disposal, the better. There are two ways to think about this:
The first way is where your software has a fixed set of resources available, such as what is available in a server. If your application could use all the resources better, and thus serve the users better, then that would be preferable. However, sometimes software cannot really sensibly make use of spare resources of the hardware it is running on.
The second way is where your software has a dynamic amount of resources available. The less resources your software needs, the less resource it needs allocated to it, then. Any unused resources can be allocated to other software than yours.
The most common resources your software should utilize optimally are:
- CPU Utilization
- Memory Utilization
- Disk Utilization
- Network Utilization
I have explored software optimization in more detail in my text about software performance optimization principles.
Security
The security level of your software will often be an important quality factor too. Software that is insecure can end up being very expensive to use for your customers - and if your customers leave you - very expensive for you too!
It is useful to know about the most basic attack vectors of your software, such as those listed by OWASP and other security organisations. You may also benefit from static code analysis, or have external companies do security reviews of your software.
Tweet | |
Jakob Jenkov |