Learn what a code review is, how to do code reviews and the common steps of a code review workflow, in this article from awesomecodereviews.com.
Here is what you will learn:
What is code review
During a code review, developers inspect source code to improve the code or to learn about it. Code review is a valuable practice in software development because it helps to improve code quality, enhances teamwork and collaboration, promotes learning and helps to share knowledge. How exactly a code review process looks differs from company to company, and often even from team to team.
Code reviews can be very formal, following strict code review checklists, similar to a Fagan inspection. Yet, they can also be very informal, where, for example, one developer asks another developer to quickly look over the code while they pass by in the office. This form of code review is often referred to as “over-the-shoulder code review”. Code reviews can be done synchronously or asynchronously.
Nowadays, developers often use a tool to conduct code reviews. It’s also common that code reviews are done whenever a small work unit is ready (e.g., on a daily or weekly basis), and that code reviews concentrate only on newly developed or changed code. Yet, some companies still perform code reviews only after major milestones have been reached, and then they review large parts of the codebase.
You see, there are many nuances to code review practices and workflows.
Common steps of a code review
Independent of the differences in the code review processes, let’s look at which common steps code reviews have to get a better understanding of how code reviews take place.
In a nutshell, a code review will follow the following six steps:
- Identify the code to be reviewed
- Prepare the code for change
- Select the reviewers
- Conduct the code review
- Discuss and address problems
- Approve or reject the code
While those six steps give you a basic mental model of a code review workflow, there are several nuances to how development teams do code reviews. Let’s look at the different steps to code reviews more closely.
Identify the code to be reviewed
First, we have to identify which code needs to be reviewed. Often this could be a new feature or module, or it could be a change to existing code. If we look ten years back, development teams would review large parts of a codebase or even a whole codebase during a code review. And such code reviews would happen every few months.
Nowadays, it’s more common that the code that’s reviewed is related to a ticket or work item a developer has been working on. This means code reviews happen much more frequently (daily or weekly), and that way less code is reviewed.
In addition, during code reviews, reviewers will nowadays only focus on code that has been touched while a developer made changes. This means reviewers look only at lines added, deleted or changed, but do not inspect the code that has not been touched. The reason for this focus stems from the code review tooling used. The code review tools often only highlight the differences between one version of the code and the other version of the code.
Prepare the code for review
Before you ask another person for a code review, you should ensure that the code is of high quality and ready for review. This starts with a self-review. A self-review is the process in which you take the time to look through your code change carefully as if you were a reviewer. The best approach is to use a code review tool or any tool that highlights the exact changes that you made (i.e. a file comparison tool, also called a diff tool). This ensures that you see the code differently, and also helps you remember what changes you have made. During this inspection, clean up the code, add comments or documentation, and make sure that the code is organized and easy to understand.
You might also want to reorganize or better name your commit messages, as they can help the reviewer to better understand your work.
After the review, you ensure that the code compiles without warnings or errors. The code should be covered by relevant tests, that have been run and passed.
It is a good code review practice to also run static analysis tools such as linters over your code and fix any errors or warnings that the tool detects before asking a human code reviewer to spend time inspecting your code.
Select the reviewer
The next step is to select the reviewer or reviewers. Reviewer selection is a very important aspect of code reviews. The review is only as good as the reviewers you selected. This means, if you chose a person that knows little about the codebase, the programming language used, or the requirements this change implements, you cannot expect them to be very helpful to improve the code. Yet, adding them might help them to learn, which is also a code review goal.
In general, appropriate reviewers are people from your own or another development team or someone with specific expertise or knowledge related to the code being reviewed. Studies recommend choosing two reviewers. But it’s not uncommon to see only 1 or up to 10 reviewers selected per code review. There are also quite a few code review tools that help during reviewer selection.
When we talk about code review, we expect that the code author and the code reviewer are not the same people. Yet, exceptionally some developers will review their own code and call it a code review. Yet, we call the activity where at least one other person than the author looks at the code, a code review, and we will refer to the activity of inspecting your own code as a self-review.
Conduct the review
The actual code review can be conducted in a variety of ways, such as in person, via email, or using a code review tool. Independent of the tooling or meeting type, during the review, the reviewer carefully inspects the code, looking for defects, problems, and opportunities for improvement.
While historically, code inspections followed a rigorous review protocol, code reviews are nowadays very ad hoc in nature. This means, reviewers seldom get instructions on how to review the code or what to look for. This uncertainty and lack of focus reduce the effectiveness of code reviews. There are common aspects code reviewers are implicitly expected to look for, such as maintainability, readability, quality and correctness of the code. Code review checklists can be very helpful to make sure reviewers focus on all important aspects and do not forget some. They also make the code review process more systematic. Finally, code review checklists are a great learning tool and help teams have more coherent code reviews, in which the quality of the code review fluctuates less with the reviewer.
Discuss and address any issues
If the reviewers find issues with the code, they discuss those with the developer. Together, the code author and the reviewer come up with solutions to the problems. This means that they either agree to make changes to the code, or they decide that changes are not necessary. Often, comments of the reviewers are also questions about the code, that do not require any changes but help the reviewer to learn about the code or approaches.
During tool-assisted code reviews, those discussions take place in written form. Written communication can easily lead to misunderstandings, as people lack facial expressions, tone or body language to understand what the other person meant. Therefore, written code review feedback needs to be carefully phrased.
While unfortunately few developers ever get training on how to give and receive feedback, there is much that can be learned. Feedback can quickly hurt feelings, or even destroy relationships. Code reviews are also known to amplify biases, and studies show that depending on age, ethnicity, or gender, developers get more or less pushback during code reviews.
Also, during code review discussions conflicts can arise, which need to be handled and managed. To make sure code review discussions are productive and do not cross boundaries, it’s important that developers are aware of conflict management strategies, and possess conflict competence. In addition, code review guidelines, as well as a code of conduct should be in place.
With the right learning and feedback culture, teams can greatly benefit from each other during code reviews, and relationships are strengthened.
Approval or Rejection
The goal of the feedback loop, in which identified issues are discussed and reworked, is to get the code into a state that is acceptable and can be approved and merged with the production codebase. Some code review tools offer the functionality to reject the change. This means the code will not be merged with the codebase. Yet, rejections of code should happen on as exceptions.
A better approach than straight-out rejecting the code is to say the code is not acceptable in its current state. Yet, after some rework and another code review round at least parts of this code change will land in production. This often happens when the code change is large, and there are many issues that need to be addressed and reworked. During this rework, often pull requests are closed without being merged. Yet, the code appears again in a new pull request.
Especially in open source, code changes are indeed rejected with the consequence that the code never makes it into the codebase. This can happen if there are too many issues and the open source maintainers would need to spend too much time giving guidance or improving the change. Another common reason for rejection is that the proposed code change implements a feature that’s not aligned with the roadmap of the product.
In company or closed source settings, rejections that lead to never merging the code should be an absolute exception and a red flag that shows that something is wrong with the collaboration or project management. Rejections during code review decrease developer experience.
Making code review decisions
But how are code review outcomes determined? There are different strategies to approve code. They differ mainly by who decides whether the code change should be accepted or changes be made to the proposed solution.
In some teams, there is only one person, such as the team lead, the engineering manager or an architect that makes the “Yay” or “Nay” decision. Such decision approaches tend to be faster, yet can make developers feel less ownership of the product.
In other companies, more collaborative decision-making processes are preferred. Here, for example, the majority of the team decides what happens to the code. Yet, in practice, often there is no clear or explicit decision-making process or criteria.
Missing group decision strategies during code reviews can lead to a slowdown of the software development process, and developers often build up resentment of code reviews.
Code review tools
Code review tools assist during code reviews by allowing reviews to be done asynchronously, highlighting the differences between one version of the code and another, allowing developers to attach feedback in form of comments to the code, and by tracing and tracking discussions and decisions.
The most well-known and widely used code review tools are GitHub, GitLab, and BitBucket. All of those code review tools are integrated with the code repository, which makes them convenient to use, as no other tools need to be installed.
There are also standalone tools that are popular such as Gerrit and ReviewBoard that work with a broader range of version control systems such as SVN, or Mercurial.
Finally, many code review extensions let you review code right within your IDE.
A new and upcoming code review tool in this category is CodeStream. But most code editors such as Visual Studio, VIM etc. have their own plugins and extensions that allow you to review code.
Each tool has its own pros and cons, yet they all support discussing code during code reviews in a similar form.
As you have seen there are many nuances to how code reviews are conducted at different companies or in different teams.
Many of the approaches, such as synchronous or asynchronous reviews, have their pros and cons, which I’ll cover in an upcoming article.
By following a structured process during code reviews and using the right tools and techniques, developers can ensure that their code meets the highest standards and is ready for production.