Code Quality Metrics: How to Evaluate and Improve Your Code

High-quality code is efficient and reliable, runs well without bugs, and meets the user’s needs. It can cope with errors or unusual conditions. It is also easy to understand, maintain, and expand with new features. Additionally, its portability means that it can run on as many machines as reasonably possible.

Programmers often work with codebases that are constantly changing. They add, delete, and modify existing code to improve speed or implement new features. All in all, they read a lot of code. This means that for them, quality equates to readability.

Unfortunately, constant code changes often cause its quality to gradually degrade. But this challenge presents an opportunity to examine what makes code readable, understandable, and of a sustainably higher quality.

What is Code Quality and Why Should You Care?

Generally speaking, the easier code is to read, the easier it is to understand and edit. Moreover, it often runs faster and with fewer errors, resulting in its enhanced maintainability and extensibility. All of this leads to faster development and fewer bugs, providing long-term cost reduction.

While all these characteristics indicate high-quality code, they provide little insight into how to achieve it. Unsurprisingly, code quality is not easily defined because it must function equally well for the programmers who use it and for the end users who only experience its results.

Producing superior code can mean using descriptive variable names, but it can also mean properly disposing of unmanaged resources. While the former is simple to implement at all skill levels, the latter is easy to overlook — regardless of seniority. Providing descriptive variable names is a basic practice, but one that greatly enhances readability. Effective resource disposal requires knowledge of the tools used and attentiveness to manage them effectively.

In order to best measure code quality, the metrics used fall into one of two groups: quantitative or qualitative.

Quantitative Code Quality

Quantitative quality measurements are those that we can define 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.

Additionally, 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 any of them were easy to read or understand.

There is also a more complex metric regarding maintainability, called cyclomatic complexity. Although we rarely encounter it, Visual Studio (for example) provides default support for its measurement.

Cyclomatic complexity calculates the number of paths that source code contains. Ifthen statements, loops, switches, and other control statements all increase your code’s cyclomatic complexity. Unsurprisingly, higher complexity means increased difficulty with maintenance and a greater likelihood that bugs will occur.

While crucial, quantitative metrics provide only part of the picture. Even 100% test coverage does not indicate that the code will be problem-free. Conversely, a high cyclomatic complexity does not necessarily ensure severe maintainability issues.

Furthermore, the interpretation of quantitative code metrics is a subjective practice. One team member may think 50% code coverage is sufficient, but another member may think 80% is the minimum acceptable result. Fortunately, quantitative metrics find balance with their qualitative counterparts.

Qualitative Code Quality

Qualitative measures cannot be expressed in numbers, but are equally significant in assessing code. Consider the importance of adherence to coding standards, using meaningful names for objects, or establishing a maximum line width across a codebase (the line width is a number, but its effect on code quality is not). 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. Furthermore, 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’s merged back into the main branch. In one respect, this process can detect issues that might have gone unnoticed. But 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

Fortunately, various tools and guidelines exist that help track and assess code quality. It is important to ensure that your integrated development environment (IDE) implements these tools before you push code to source control. For example, a linter can check whether your code adheres to [company] coding standards and can run on a build or before a commit.

However, it is sometimes 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. Many CI/CD tools offer easy ways to integrate code quality tools. For example, CircleCI has Orbs for ESLint, Pylint, and Sonarqube, among several others.

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 may 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, common typing errors, and even SQL UPDATE and DELETE statements without WHERE clauses.

There are some alternatives, but Sonarqube has become the de facto standard for scanning code for issues. An effective code analyzer can inform you about potential problems, best practices, bugs, and even security hazards.

Whether using a linter or Sonarqube, you can make a build fail on certain issues or send out an email with 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 is below a certain threshold.


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. Regardless, it’s never too late to start measuring and improving your code quality. CircleCI has many code quality integrations built right into its pipelines for this exact purpose. You can visit their website to learn more and start improving your code quality today.

If you’re interested in developing expert technical content that performs, let’s have a conversation today.



If you work in a tech space and aren’t sure if we cover you, hit the button below to get in touch with us. Tell us a little about your content goals or your project, and we’ll reach back within 2 business days. 

Share via
Copy link
Powered by Social Snap