The Engineering Leader’s Guide to Code Quality Metrics
Tech moves fast. As deadlines get closer, it can be tempting to code fast to get it shipped as quickly as possible.
But fast and good don't always equate. And worse, where there's dud code, there's a chump stuck refactoring their predecessors' dirty code and dealing with a mountain of technical debt. And no one wants that to be you.
Fortunately, engineering leads can set the standard with practices prioritising code quality metrics and health.
In this article, I’ll cover…
- Why code quality matters
- The most important code quality metrics
- How to handle code quality issues
Why code quality matters
Code quality is crucial for software development as it determines how well the codebase functions, scales, and maintains over time.
Good quality code ensures the software is stable, secure, and efficient.
On the other hand, poor quality code can lead to bugs, security vulnerabilities, performance issues, and scalability problems.
Code quality impacts the amount of technical debt that accumulates over time.
Technical debt refers to the cost of maintaining a codebase developed with suboptimal practices or shortcuts. It accumulates over time, and if left unchecked, it can make it difficult or impossible to maintain or improve the codebase without significant effort or cost.
Due to deadlines, budgets, and other constraints, developers are often forced to make tradeoffs between quality and speed, and accumulating technical debt is inevitable.
However, accumulating technical debt imprudently can increase the risk of bugs and security vulnerabilities, make adding features harder, slow development, and even require a complete codebase rewrite in extreme cases.
But how do we get to this place? No single metric or focus point can fully capture code quality. Rather it's the combined efforts that help build and maintain healthy codebases. Here are some of the mission-critical metrics you need to prioritise:
Let's be clear. Code churn is a normal part of the development process. But the amount of code churn also helps you measure your development team's efficiency and productivity. If the bulk of a dev's time is spent writing and rewriting the same bits of code, it can suggest two things:
1) Problem code is being tested, workshopped, and refined. This is a good thing, especially when dealing with a sticky problem or challenge that requires regular reworking as part of an evolutionary process. Time spent learning that results in a win is always well-spent. Code churn in response to customer feedback is a plus.
2) There's a bigger problem. Code churn that consistency results in low work output can be a sign of:
- Poor programming practices
- Lack of experience or skill at self-editing
- Low morale or burnout
- External woes like ever-changing demands from other departments or external stakeholders. (Yep, this is why they pay you the big bucks).
Besides talking regularly with your team about their process and regular code reviews, you can also measure code churn using various tools such as:
In most companies, marketing and editorial departments have a style guide, a living document that outlines the rules for written content – think everything from grammar to whether you write 1M or 1 million.
Dev teams should also have coding conventions – they might be specific to particular projects or across the whole team.
After all, code is also about interpersonal communication, not just machines. And a shared language helps create quality clean code by improving readability and maintainability. It also helps team members understand each other's code and easily find files or classes. Some common coding conventions:
- naming conventions
- file organisation
- architectural patterns
You might think of using a code linter to highlight code smells or security gaps, but you can also use it to monitor code conventions. Tools include:
While at it, spend some time on an agreed-upon approach to documentation. Think of it as passing a torch or baton of knowledge from past you to future you.
Ok, some code is just an intricate maze born of pain. But it may also be an impenetrable jungle that's impossible for anyone to understand except the original person who wrote it. It gets shuffled to the bottom of the pile every time the team talks about refactoring to reduce technical debt.
And remember, many devs only stay in one role for a couple of years, so that person could spread their jungle of complex code like a virus across multiple organisations if left unchecked. Terrifying.
But back to business. Simply put, code complexity refers to how difficult code is to understand, maintain, and modify. Overly complex code can also be at risk of bugs and may resist new adds.
There are two main methods of measuring code complexity:
- Cyclomatic Complexity measures the complexity of a program based on the number of independent paths through the code. It is a quantitative measure of the number of decision points in the code, such as if statements and for/while loops. The more paths through your code, the more potential problem areas in the code that may require further testing or refactoring.
- Halstead Complexity Metrics, which measures the size and difficulty of a program based on the program length, vocabulary size, the number of distinct operators and operands, the number of statements, and the number of bugs per thousand lines of code.
These metrics evaluate software quality and maintainability and predict the effort required to develop, debug, and maintain software systems.
That said, Halstead Complexity Metrics don't factor in other important metrics like code readability, performance, security, and usability, so it's not something to use as a stand-alone tool. Check out Verifysoft if you want to dig into the metrics more.
Code maintainability is pretty much what it sounds like – how easy it is to maintain and modify a codebase over time. Poorly maintained code causes delays as it takes longer to update and can stand out as a critical flaw against your competitors.
But done well, it pulls together all the good stuff, including code clarity, complexity, naming conventions, code refactoring, documentation, version control, code reviews, and unit testing.
So it's about a broader commitment to code quality rather than a single task or tool. And it's always worth remembering that, like refactoring, you'll maintain your and other people's code a long time after the first write.
Fortunately, there are automation tools aplenty from the get-go when it comes to maintainability. For example, static code analysis tools identify bug risks, anti-patterns, performance issues, and unused code.
New Bugs vs Closed Bugs
Every bug in your software is a small piece of technical debt that accumulates over time. To keep track of your technical debt, your engineers must track and document every bug, including when they are fixed.
One way to measure your code quality is to compare the number of new bugs discovered to the number of bugs that have been closed. If new bugs consistently outnumber closed bugs, it's a sign that your technical debt is increasing and that you need to take action to manage it effectively.
Tracking new bugs versus closed bugs helps identify potential issues in the development process, such as insufficient testing, poor quality control, or lack of resources for fixing bugs. By comparing, you can make informed decisions about allocating resources, prioritising bug fixes, and improving your development practices to reduce technical debt and improve code quality over time.
Stepsize helps modern engineering teams improve code quality by making it easy to identify, track, prioritise and fix technical debt or code quality issues.
Create, view and manage issues directly from your codebase with the Stepsize tool. Issues are linked to code, making them easy to understand and prioritise.
Use the codebase visualisation tool to understand the distribution of tech debt and code quality issues in the codebase. Use powerful filters to understand the impact on your codebase, product, team and business priorities.
It's important to remember that effective code quality management involves more than just relying on a single metric or tool.
Instead, engineering leads need to prioritise embedding a commitment to code quality tasks and tools into the daily workflow to ensure consistent improvement over time.
This includes helping team members develop good code hygiene through habit stacking and skill development, which can significantly benefit their careers.
Tracking and prioritising technical debt is a critical aspect of increasing code quality. By doing so, teams can make a strong business case for refactoring the essential parts of their codebase, leading to more efficient and maintainable software in the long run.