Code quality metrics: How to evaluate and improve your code
Senior Technical Content Marketing Manager
Code quality is a metric that measures the overall health of software in terms of its maintainability, reliability, and robustness. High-quality code is efficient and reliable, runs well without bugs, and meets user needs. It can cope with errors or unusual conditions. It is also easy to understand, maintain, and expand with new features.
Development teams work with codebases that are constantly changing. They add, delete, and modify existing code to improve speed or implement new features. That means they read a lot of code, so for them, quality equates to readability.
Unfortunately, constant code changes often cause code quality to gradually degrade. This challenge presents an opportunity to examine what makes code readable, understandable, and of a sustainably higher quality. In this post, we’ll explore what code quality is and how you can measure it on your own projects to help ensure that your codebase remains robust and maintainable.
What is code quality and why should you care?
Code quality describes the overall excellence of software in terms of functionality, structure, and adherence to best practices that enhance maintainability and readability. Common factors used to measure code quality include code complexity, adherence to coding standards, and the presence of vulnerabilities or bugs.
The easier code is to read, the easier it is to understand and edit. Simpler code runs faster and with fewer errors, making it easier to maintain and iterate on. Faster development and fewer bugs add up to long-term cost reduction. These characteristics define high-quality code, but how can development teams make code easier to read?
You can start by using descriptive variable names, a basic best practice that greatly enhances readability. Descriptive naming is easy to implement at all skill levels.
Properly disposing of unmanaged resources also helps, but requires experience and focus. Even senior developers may not know where to start.
In order to best measure code quality, it’s best to use both quantitative and qualitative metrics.
Quantitative code quality
Quantitative quality measurements are metrics that can be defined with a numerical value. For example, code coverage — the percentage of code that runs during unit tests — is a discrete value between 0% and 100%. The greater the value, the less chance there is for undetected bugs. Therefore, code quality is likely higher.
Consider the average number of lines of code (LOC) per function or class. Generally, fewer lines result in greater readability. Most seasoned programmers have undoubtedly encountered many 1,000+ LOC functions, and it is unlikely that those were easy to read or understand.
While crucial, quantitative metrics provide only part of the picture. Even 100% test coverage does not indicate that the code will be problem-free. While the metric itself is an objective measure, the interpretation of quantitative code metrics is subjective. One team member may think 50% code coverage is enough, but another member may think 80% is the minimum acceptable. Fortunately, quantitative metrics find balance with their qualitative counterparts.
Qualitative code quality
You cannot express qualitative measures in numbers, but they are an important way to assess code. Consider the importance of following coding standards, like using descriptive names for objects or setting a maximum line width for code readability. Together, these practices can form the foundation of excellent code.
Qualitative measures can be highly subjective. Some programmers prefer longer variable names that express their purpose, while others feel more comfortable using truncated names like ord
or cust
. Naming conventions vary depending on the language. This makes qualitative metrics more difficult to define, especially for those whose primary languages may differ from those of their peers.
One vital way to enhance code quality and maintain open discussion about subjective quality metrics is to perform regular code reviews. In this process, coworkers can rate the overall quality of one another’s code.
For example, a team of five developers can each commit code that must be reviewed and accepted by at least two peers before it can be merged back into the main branch. In one respect, this process can detect issues that might have gone unnoticed. More importantly, programmers can learn from one another and stay consistently updated on the latest software changes.
Continuous quality: Measuring code quality in a CI/CD pipeline
There are many tools and guidelines to help development teams track and assess code quality. No matter what tools you use, it can be easy to forget to check code before pushing it to source control. That’s why it’s important to integrate these tools in your continuous integration and continuous deployment (CI/CD) pipelines. Doing so ensures that your code quality checks are run on every commit to source control.
For example, a linter can check whether your code adheres to your company’s coding standards and can run on a build or before a commit. Many CI/CD tools offer easy ways to integrate code quality tools. For example, CircleCI has orbs for ESLint, Pylint, and SonarQube. There are many more available.
ESLint can check your JavaScript syntax as well as whether you’ve properly used the var, let, and const keywords. It also assesses whether your variables have an unintended scope, which may lead to unanticipated behavior. Pylint performs the same tasks for Python. You can configure linters to meet your specific needs and preferences.
SonarQube is a powerful tool that can check for thousands of issues in various programming languages. It can detect duplicate code, potential infinite duplication, undiscarded disposable resources, hard-coded credentials, and common typing errors. It even finds SQL UPDATE
and DELETE
statements without WHERE
clauses.
SonarQube has become the de facto standard for scanning code for issues, but there are many capable alternatives, such as Code Climate. An effective code analyzer can inform you about potential problems, best practices, bugs, and even security hazards.
Whether using a linter or code analysis tool, you can make a build fail on certain issues or send out an email or Slack alert that lists all errors and warnings.
It is also vital to set up unit tests and run them in your CI/CD pipeline. Your build will fail if a unit test fails. You can also fail your build if your code coverage falls below a certain threshold.
Conclusion
Code quality can improve the readability, maintainability, and extensibility of your code. Better quality means less technical debt and fewer bugs, leading to easier development and lower costs.
Building code quality into your development process does not have to be difficult. Ideally, you have done so from the beginning, but it’s never too late to start measuring and improving your code quality.
To learn more about metrics you can use to evaluate and improve your team’s velocity and performance, read How to find and monitor engineering metrics for team success. To further enhance your project management and streamline your development process, consider signing up for a free CircleCI account, which will enable you to automate and optimize your software delivery workflows.