Many people have explored the concept of code reviews at length. They continue to be an integral part of the developer experience, for reasons I will discuss below. But, like most things that challenge us to improve, they can easily become awkward and a host for a variety of toxic behaviors. A number of articles have been written about proper code reviews, and they usually center around the idea of “being nice.” But I’m going to hone in on a few slightly different signs of toxicity in your code reviews. And with each sign, I’ll help you understand how you can change your team’s behavior to create a healthier environment.
The Purpose of a Code Review
A team may have multiple reasons for doing code reviews, but most of them focus on code quality. We want to catch potential errors earlier, when they’re inexpensive to deal with. Also, we want to ensure the internal quality of our code is healthy, so that we can have a low cost of ownership. We may even have specific, strategic refactorings we’re trying to perform across multiple user stories. Using code reviews provides a place for us to scan for these things and coach the team in a better direction. But such well-intentioned efforts can easily turn toxic.
The Five Signs
The five following instances are signs of a toxic review culture.
Having a Gatekeeper
Let’s start off with the gatekeeper anti-pattern. This is when one person on the entire team is doing the code reviews. It’s often the technical lead or a senior developer. This is a bad sign for many reasons. First off, this encourages the person to believe they have the “right” answers and everyone needs to learn them. We will cover more of this below. Second, it helps create a “cult” of personality where everyone is matching this person’s preferred style instead of leveraging their own creativity. Finally, it usually significantly slows the team down to have only one person who can perform a certain task before code deploys to production.
Instead, focus on collaboration. If the team believes this person to be the most senior, the person should be coaching the other team members to make healthy code decisions. And they cannot coach if the team feels too disempowered to experiment and find interesting ways of automating. The team shouldn’t fear reprimand for doing things differently than the gatekeeper. There is the argument that if the team is mostly junior developers, they need to be vetted constantly before they’re ready to code on their own. But, even in this case, it’s better to mob program than to create a gatekeeper.
Saying “This Is Wrong”
For some reason, many software developers seem to love absolutes. Something is always “right” or “wrong.” The code is either “good” or “bad.” What’s wrong is to use such statements, especially in your code reviews. Our industry isn’t mature enough to have a formal set of laws. We’re still discovering techniques and figuring things out. On top of that, what made sense for one team may not make sense to another. Different system forces and different people mean we need different ideas. Also, it’s really easy for a person to think they themselves are “wrong” as a developer. People tend to take things personally.
Take bridges, for example. Is a steel suspension bridge better than a stone arch bridge? Is a larger bridge better than a smaller one? Of course not. The stone bridge is cheaper to build but still gets the job done. A small bridge is all that’s needed to cross the river. Anything more is actually wasteful and would be hard to use. Imagine dropping a half-mile-long suspension bridge on the street just to cross your local creek!
Instead, if we feel a “wrongness” inside of us, we should attempt to understand why that feeling popped up. Ask yourself these questions: Why does this feel wrong to me at this time? What is this going to make more difficult? When we walk back a step from that feeling, we’ll actually uncover a perspective that may have been implicit. Share this understanding with the coder. Don’t just say “Doing two for loops is wrong.” Rather, you might say “If we use two for loops then this will execute slower.” That can spur a conversation instead of making the coder feel bad. If you hear someone else use these terms, ask them questions like “Can you help me understand why you feel this is wrong?” This will help them stop and think, and hopefully they can explain their intent rather than using blanket absolutes.
Saying Only Negative Things
It’s so easy to point out what we disagree with in all things, not just code reviews. It’s much harder to point out the things someone did well. I don’t know exactly why this is. I’m sure we could dig up all sorts of research on it, but my experience tells me this is how we naturally are. But when we only say negative things in a review, we reinforce the message “Everything you do is bad. You are not good at this.” This can have long-lasting detrimental effects on our coworkers. They may withdraw more from the team. They’ll be less likely to try something risky or new, fearing more negative feedback.
Instead, find little things that you can celebrate in their code. Look for efforts to meet your shared goals and call that out. Don’t give compliment sandwiches but do give compliments. If you find yourself on the receiving end of negative reviews, coach your teammate out of it. Ask “What things did you find that you felt were done well?” This will help your coworker think explicitly about the code in a positive light.
Missing the Forest for the Trees
One of the dangerous things about code reviews is that they create a kind of vacuum. You may look at them through a lens of a GitHub pull request or just scan the code in your IDE. Whatever the method, we’re focused on the minutiae of the code rather than its overall place in the codebase. This can easily cause people to focus on the most obscure issues. Perhaps someone says we didn’t pluralize a variable name. Or that we should use two lines to separate method calls rather than one. The point is when reviewing we need to consider the larger goals, as we discussed above. We want to add valuable input, not noise. When we focus on minutiae, we also risk overwhelming developers who may be focusing on a particular area of their coding skills.
Instead, ensure you focus on what’s important for your team at the moment. You may have an overarching initiative or push for the code in a certain direction. Focus on the quality aspects of the code that meet that, rather than arbitrary issues. Your coworker may be at a certain maturity in their coding skills. Understand where their head is at and hone in on code that helps them drive toward the next level of maturity. If you don’t know where they’re at, ask them “What quality concerns do you want to focus on in your code?”
Having a 100% Manual Process
The final sign of toxicity may be the worst: 100% manual code reviews. We’re professional automaters. And we’re paid, on average, a lot of money to automate things, saving costs for our client or employer. We need to turn this lens inward and relentlessly automate internal aspects of our project, not just the code itself. This includes code reviews. There is a myriad of options that let us codify code standards and perform static analysis on our codebase. Why would we tolerate the costs of mostly manual code review?
Instead, use static analyzers, like CodeIt.Right. Use a common code style setting across your team for your IDE. These tools can catch more things than a human can and in a fraction of the time. Save your team the annoyance of looking for the little things. Let them focus on the big things, the things too complicated or too subtle for your computer to handle.
Detox Your Code Reviews
Now that you know the signs of toxic code reviews, detoxify. Help coach your team to new behaviors. Be an inspiration to your team by focusing on the positive, not only the negative. Install static analyzers and style settings. Understand the behaviors you may possess in yourself and always strive for improvement.