Quality isn't a four letter word
Peter Harrison
Posted on November 4, 2024
The motivation for writing this article is to some extent in response to a post online about the utility of pull requests. Pull requests are a specific artifact of using git as a source code version control system, where a developer will raise a request to pull code from their branch into the main branch. Before git we had commit reviews where the code had to be reviewed before it was committed, but didn’t have the online tooling we do today around pull request management. While the use of git and online tools supporting pull requests has made code review pervasive, the benefits of this process are lost. This article addresses what has gone wrong, and how we can do better.
Quality and the art of Software Development
What do we even mean when we talk about quality in software? There are two perspectives from which we can look at quality. The first is from the user’s point of view. Does the software do what I need it to? Does the software have defects which prevent me doing what I need to? Is the software easy to understand and use? Does the software force me to jump through many hoops to achieve what should be simple? From a user’s perspective, it isn’t just about being defect free. The lack of a feature might be perceived as a defect. This is a source of frustration for developers who might see a lack of a feature as a new feature request rather than a defect.
The developer also cares about the same kind of quality as the users do, in that it must work and be functional. Often a developer is not responsible for a whole system, a single web service for example. The web service will have an interface specified in the design. If the web service meets the requirements without defects the developer will consider it high quality, even if the software isn’t utilizing it correctly. Perhaps more importantly there can be a difference of perspective, especially when software developers do not experience the use of the software.
On the other hand, there are aspects of quality that are hidden from the user; the source code itself. Just because the code achieves the same thing for a user does not mean it is equal quality. Quality source code should be easy to read and understand. Ideally it should be as simple as possible. Most software development is modification of existing code, so being able to make changes without breaking it is critical. What we don’t need is ‘clever’ code which is almost impossible to decipher.
Quality is baked in
Think of software quality like baking a cake - you can't wait until it's done to add the essential ingredients. The waterfall approach tried exactly this, treating quality as a final inspection step. By relegating testing to the end of the project, teams discovered too late that quality issues were already baked into their code. The result? Projects drowning in bug lists and teams stuck in death march fixes.
Defects don't mysteriously appear in code - they're introduced during development. This simple truth leads to a crucial insight: quality must be a shared responsibility across the entire team. While dedicated testers were once common, modern teams often embed quality assurance throughout the development process. This shift emphasizes preventing defects through careful acceptance criteria and automated testing rather than just finding them later.
Quality isn't a phase or a checkpoint - it's a mindset that must be present in every commit, every review, and every deployment. When quality is truly baked into the development cycle, it becomes as natural as any other development practice.
The role of reviews
My first experience of code review highlights how our practices have evolved. I remember sitting in a room with several other developers reviewing huge paper printouts of my code. While these sessions did catch coding convention violations and occasionally identified better approaches or defects, they focused heavily on formatting and style over substance. Today we understand that effective code reviews need a broader focus, considering both the code's functionality and its maintainability.
Examination of the code itself should be a small part of the review. My approach to review is linked directly to answering the questions of quality we raised earlier.
- Does the solution meet the user requirements specified in the story?
- Has the software been run and checked to perform the new requirements?
- Are there unit tests to prove it is functioning as expected?
- Does the code meet standards such as simplicity and ease of maintenance?
When you look at these you will see that you can’t determine the first three by simply looking at the code. You need to actually read the requirements, check the software is functioning as expected in a test environment and observe that the unit tests are running. But that sounds like a fair amount of work.
From a practical point of view, are we really going to pull their branch, build the system and run unit tests for every pull request? With the advent of pull request tools we have seen code review become simply eyeballing the code. The problem is that eyeballing code is not going to find most defects.
Face-to-face vs asynchronous code review
Let me first define what we are talking about. Face-to-face does not imply co-location. It means being in the same place, virtual or not, at the same time reviewing the code together. Asynchronous code review is performing a review without the presence of the author of the code.
Modern tools have made it easy to view a diff of a pull request. You can see all the changes to the code across multiple files. It is easy to review just the sections of code that are being modified. It seems to have become somewhat the norm for code reviews to involve simply eyeballing the diff and approving.
If you are going to take this approach, there are some ways to automatically validate code to some extent. This would include building the code, running unit tests and then evaluating whether there is unit test coverage for the new code. Without a passing mark on the commit build you should not be able to have the pull request approved.
It also might be that the code is automatically rolled out into a test environment so that it is possible to test the functionality prior to approval. If user acceptance tests are also used it would be possible to automate the functional tests using Selenium or other acceptance test tool. So, it is possible to set up asynchronous processes which retain many of the considerations required to maintain quality.
While asynchronous reviews have their place in modern development workflows, they come with hidden costs. Reviewers often hesitate to raise subtle issues, limiting themselves to clear-cut defects that are easy to explain in written comments. The formal nature of pull request tools, where every comment potentially blocks approval, can make developers overly cautious. This creates a stilted conversation about code quality, with long cycles of feedback and response, and leaves authors uncertain about when or how their code will be reviewed.
Face-to-face reviews, whether at the same machine or through screen sharing, enable a different kind of conversation. The immediate back-and-forth allows for nuanced discussions about design choices and coding approaches. Before even looking at code, reviewer and author can align on requirements and design intent.
This human connection transforms what could be a mere inspection into a collaborative session focused on understanding and improvement. With modern tools, much of the preparatory work can be completed before the review begins. Build verification, unit test results, and even initial static analysis can be automatically checked when raising the pull request.
This lets the face-to-face time focus on deeper aspects of code quality. The primary advantage of real-time communication is the ability to explore implementation decisions in context. Viewing whole files rather than just diffs helps identify broader patterns and potential improvements.
Anti-patterns like code duplication become more apparent, and alternative approaches can be discussed and implemented on the spot. Small improvements, from variable naming to structural changes, can be made collaboratively during the session.
Importantly, this collaborative approach transforms code review from a quality gate into a teaching opportunity. Team members share knowledge and techniques, experienced developers mentor newer ones, and everyone contributes to improving the codebase. In an increasingly remote world, these interactions become crucial moments for team building and knowledge transfer. Even in office settings, code reviews provide rare opportunities for focused, constructive collaboration.
Productivity through Quality
Quality processes are sometimes misunderstood as bureaucratic overhead, a top-down imposition of compliance requirements. In reality, they are fundamental drivers of both product quality and team effectiveness. When developers embrace quality practices as core professional responsibilities, they contribute not just to better code, but to a more sustainable and satisfying development process.
High quality and low defect rates are hallmarks of high performing teams. These teams understand that investing in quality early prevents the downward spiral of accumulated technical debt, endless bug fixes, and eventual project failure.
Modern development environments have automated many aspects of quality management. Continuous integration, deployment pipelines, and IDEs with built-in analysis tools have made it easier than ever to maintain high standards. However, these tools complement rather than replace human judgment and collaboration.
Code reviews remain vital, not just for finding defects, but as opportunities for knowledge sharing and team growth. When done well, they foster a culture of collective ownership and continuous improvement. Teams that embrace this collaborative approach to quality build not only better software, but also stronger, more resilient development organizations capable of sustaining excellence over the long term.
Posted on November 4, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.