IN THIS SECTION, YOU WILL: Get an overview of ISO/IEC 25010 standard that provides guidelines and recommendations for evaluating software product quality.
ISO/IEC 25010 is a standard that provides guidelines and recommendations for evaluating software product quality. It is a part of the ISO/IEC 25000 series, which encompasses a set of international standards for software engineering.
The standard identifies several quality characteristics that should be considered during evaluation. I have used four of them in practice and can recommend them as a pragmatic way to assess and discuss the quality of software systems:
- Maintainability: The ease with which the software can be modified, corrected, adapted, or enhanced.
- Security: The software’s ability to protect information and data from unauthorized access, disclosure, alteration, destruction, or disruption.
- Performance Efficiency: The software’s ability to perform its functions efficiently, considering resource utilization.
- Reliability: The software’s ability to maintain a specified level of performance under stated conditions for a defined period.
Definition: The degree of effectiveness and efficiency with which the intended maintainers can modify a product or system.
- Analyzability: The degree of effectiveness and efficiency with which it is possible to assess the impact on a product or system of an intended change to one or more of its parts or diagnose a product for deficiencies or causes of failures, or identify parts to be modified.
- Modifiability: The degree to which a product or system can be effectively and efficiently modified without introducing defects or degrading existing product quality.
- Testability: The degree of effectiveness and efficiency with which test criteria can be established for a system, product, or component, and tests can be performed to determine whether those criteria have been met.
- Modularity: The degree to which a system or computer program is composed of discrete components such that a change to one component has minimal impact on other components.
- Reusability: The degree to which an asset can be used in multiple systems or building other assets.
- Keep Systems Small: The overall size of the source code of the software product matters. Systems with about 200,000 lines of code are frequently challenging to maintain.
- Organize System in Limited Number (e.g., 7±2) Balanced Components: When a system has too many or too few components, or if components differ in size significantly (e.g., you have 80% of code in one common component), it is considered more challenging to understand and maintain.
- Couple Files Loosely: Software products where more source code resides in files strongly coupled with other files are deemed more challenging to maintain.
- Keep Components Loosely Coupled: Hide most files in a component from direct dependencies from other components.
- Avoid Duplication: Avoid the occurrence of identical fragments of source code in more than one place in the product.
- Write Short Units of Code: Keep units (e.g., functions, methods) small, with many practitioners recommending units to be shorter than 30 lines. Short units are also much easier to unit test.
- Write Simple Units of Code: Keep the number of decision points (so-called McCabe index, e.g., if, while statement) per unit low, ideally below 5.
- Avoid Many Parameters in Unit Interfaces: A large number of parameters in a unit are deemed more complicated to maintain.
The degree to which a product or system protects information and data so that persons or other products or systems have the degree of data access appropriate to their types and levels of authorization.
- Confidentiality: Ensures that data are accessible only to those authorized.
- Integrity: Prevents unauthorized access or modifications.
- Non-repudiation: actions or events can be proven to have occurred.
- Accountability: Actions of an entity can be traced uniquely to the entity.
- Authenticity: The identity of a subject or resource can be proved to be the one claimed.
- Protect Data Transport: Protect data transport with a sufficiently robust protection method, minimizing caching of sensitive data.
- Protect Stored Data: Prevent or restrict access to data stored physically. Encrypt sensitive data. Correctly applying a one-way hash to the data.
- Verify Input and Output: Reject invalid system input. The rejection should not disclose information. Validate within the system, validated against a whitelist. Prevent injection and overflow vulnerabilities. Escape all output. Never unnecessarily expose implementation details.
- Uniquely Identify Actors: Identify and record system actors in a way that points uniquely to a specific actor. Include detailed traceable information, such as location or origin.
- Enforce In-Depth Authentication: Enforce authentication for all system functions and all uses. Use an intrinsically robust authentication method. For failed authentication, do not perform any tasks or expose information.
- Enforce In-Depth Authorization: Authorize within the system so the user cannot circumvent it. Authorize for every system function and at every attempt. If authorization fails, record this event and inform the user only that authorization failed. Give users the least possible privileges.
- Manage User Sessions Securely: Create and expire sessions and tokens securely.
- Keep Evidence: Allow non-repudiation and accountability. Keep the proof that an actor actively approved and performed an action. Store it securely, and facilitate retrieval and analysis.
- Manage Users Securely: Implement a secure and automated process for user sign-up, blocking and removal, and management of user credentials.
Definition: Performance relative to the resources used under stated conditions.
- Time Behavior: The degree to which a product or system’s response, processing times, and throughput rates meet requirements when performing its functions.
- Capacity: The degree to which the maximum limits of a product or system parameter meet requirements.
- Resource Utilization: The degree to which the amounts and types of resources a product or system use meet requirements when performing its functions.
Performance Efficiency Tactics
- Observe System Performance: Know the system’s actual performance and support problem analysis and resolution by measuring and monitoring the system.
- Optimize Internal Communication: Limit the number of steps, usage of small messages, and transformations in inter-process communications.
- Limit External Communication: Limit usage of external services and associated uncertainty, especially if the system has no strong guarantees over the external service’s time behavior.
- Optimize Common Transactions: Identify the most common and critical transactions, and apply standard strategies for their optimization.
- Scale Transaction Capabilities: Make it easy to increase transaction processing capacities when needed, both for individual components and the whole system.
- Scale Data Capabilities: Take care of the volume and characteristics of the data.
- Isolate External Influences: Control or exclude external influences that may impact the performance and the consistency of response times.
- Provision Resources Elastically: Accommodate variations in workload. so that the consumed computer resources and associated costs of a service rise and fall proportionally to the workload.
The degree to which a system, product, or component performs specified functions under specified conditions for a specified period.
- Maturity: The system is thoroughly tested and has a low manual maintenance effort, minimizing the number of potential errors in production.
- Availability: The system is thoroughly tested and has a low manual maintenance effort, minimizing the number of potential errors in production.
- Fault-Tolerance: Fitted with mechanisms to ensure a certain error tolerance level, ensuring that not every error results in a system failure.
- Recoverability: Should the system fail despite all efforts, it has mechanisms to either recover fully automatically or support human intervention for fast recovery.
- Isolate Faults: Prevent faults propagating from one to other components.
- Prevent Inconsistent States (Transaction Handling): Prevents inconsistent states and data in the presence of errors.
- Avoid Single Points of Failure (Redundancy): Redundancy determines to which extent a system is vulnerable to a single point of failure.
- Automate Deployment: The faster a system can be (re)deployed, the faster new versions can be put into production, enabling more rapid recovery from errors and failures.
- Make System Autonomous: Avoid the dependency of a system on human intervention to stay operational.
- Test Reliability: Make test loads resemble production loads.
- Implement Failover: Make switching to another component easy when one fails.