Reviews point out problems in somebody’s work. Unfortunately, both giving and receiving criticism can be hard. To successfully introduce reviews, we must overcome this resistance. Since finding (and later removing) problems is the primary goal of reviews, this challenge is inherent—no review process can avoid it. We can, however, make receiving review results much easier. This post describes two simple but effective practices we use in our code reviews.
If I request a review for my code, I request feedback for my work. From a rational point of view, I am aware that all problems a reviewer finds help me improve my work and become a better programmer. From a rational point of view, I thus embrace criticism to improve. From an emotional point of view, however, a request for feedback is also a hope for praise. Secretly, I hope that the reviewer will like the code.
Unfortunately, review results do not match this expectation. Reviews do not report praise. At all. Instead, they exclusively report problems and points for improvement. The image below shows an exemplary review. The left side depicts the reviewer’s perspective: while there are two remarks (red), the rest of the code is fine (green). In contrast, the author receives only the remarks and—consequently—sees only the criticism.
From a process perspective, this is effective; no time is wasted on comments that don’t improve quality. For example, you never find review comments like »TODO: keep up the good work «. From a social perspective, however, this results in a strong mismatch between my emotional expectation as an author (I think the code is great and I expect praise) and the review results I get (exclusively problems).
The key to avoid the resulting friction is to adapt author expectations:
Even the best programmers don’t write perfect code in their first draft. It’s simply impossible. The reviewer sees problems that are hard to spot for the author. Even after 7 years of working with the same colleagues in the same team and process, it is very uncommon that a non-trivial change (say affecting more than 20 lines of code) passes review without comments. It is even expected that a change you make receives many review comments which is not a sign of bad work.
Review comments target the code, not the author. They are never criticism of person or character, but always aim to improve the code.
Since the feedback mismatch is on the emotional level, reading about how to set your expectations is as helpful as hearing »don’t be nervous« right before your exam—true, but hard to operationalize. What works better for us is to adjust the review process to build up and reinforce these expectations:
Every programmer that receives reviews from others also writes reviews.
How does this change expectations? Finding problems in code from others makes me less surprised that my code contains problems, too. In addition, reviewing code is an exercise in program understanding. You think about all kinds of aspects of the program, but you don’t think much about the author of that piece of code. Consequently, when you receive reviews, it is easier to separate them from yourself.
Expectations are set early and hard to change later on. Hence, it matters how you introduce new team members to reviews. This leads to our second rule:
A new team member performs a review before his own code gets reviewed.
Starting with reviews has the additional benefit that a new member learns a lot about coding conventions, code formatting, existing libraries, … before writing his own first line. Many established conventions are then mimicked and don’t have to be criticized in the first reviews of his own code—thus reducing review effort.
This is in stark contrast to what we see in many organizations that perform reviews. Often junior members are rigorously reviewed before they may commit code or perform reviews themselves. We have made better experiences with reversing this order.
Our latest related blog posts.