Praising with faint damnation
It seems that the humble code review evolved when nobody was looking — and now we’re all struggling to catch up, whether we realise it or not.
At one point code review served as an important stage-gate to prevent bugs, security vulnerabilities, and other code quality issues from getting into production (with debatable degrees of success, but let’s not get into that here).
However, now that we’re in the golden age of devops, your CI pipeline should be catching the vast, vast majority of quality and security problems, long before your pull requests get to the review stage.1 As a result, it should be very rare that code review uncovers a problem severe enough that it should prevent the branch from getting merged.
To stay relevant, code review has evolved into a practice for facilitating cross-training and upskilling within your team. It gives your team members a chance to familiarise themselves with what’s happening in other parts of the codebase, and it can be an exceptionally effective way for your senior developers to teach and reinforce software design concepts for your junior and intermediate developers.
But most developers haven’t caught on to this just yet. Far more often than not, developers still approach code reviews with the mindset of hunting for problems. As a result the most positive review a developer can hope for is an absence of comments pointing out any major problems with their code, and only a few quibbles on minor points of style or practice — effectively praising with faint damnation.
It doesn’t have to be this way! Here are some ideas you can communicate to your senior developers to get them out of this trap and start getting real value out of code reviews:
Since they aren’t yet familiar with software design concepts, junior (and intermediate) developers can sometimes luck into writing something the right way without realising it. Calling out correct usage of design patterns and adherence to software design principles in the code review (and explicitly naming the principle or pattern!) can be a huge boost for that developer’s learning.
This is also a great way to reinforce concepts that you are currently coaching the developer on. Comment on instances where you see them applying those learnings correctly, so that they have concrete examples to help them better understand the technique and recognise the progress that they are making. As a bonus, the event will be cemented in their mind, so you can bring it up in your next one-to-one with them to build a bridge to the next concept you want them to learn.
Because they don’t (yet) have years of experience doing things a particular way, junior developers are often ridiculously good at discovering libraries, features, and techniques that their more senior teammates didn’t know about. Seeing a simple, “I didn’t know we could do that! Great find!” in their code review comments is highly motivating for a junior developer (or of any skill level, really) and it will help bolster their confidence and independence.
It makes junior developers less intimidated to review (and learn from!) their teammates’ code. Junior developers struggle continually with imposter syndrome, and this makes them very hesitant to review code written by other developers…especially when they think that the job of the reviewer is to identify problems with the code! But when your junior developers see their teammates praising good practices and calling out learnings in code review, it shows them that their perspectives are also valuable, and they’ll be more encouraged to participate.
Praising well-designed code helps solve the “tone problem” of code reviews. An overwhelming majority of code review is conducted asynchronously, usually by leaving typed comments on a pull request, and we all know how easy it is to read a negative tone into written messages, intended or not. By encouraging a practice of calling out the good stuff during code review, it cultivates a more positive mindset for both the code author and the reviewer, leading to less conflict and more productive discussions.
Thanks to advances in the field of devops, automation has created the space for your developers to engage in more thoughtful and positive discussions during code review.
Don’t fall into the trap of praising with faint damnation. Praise with genuine praise, and your code reviews will become catalysts for multiplying your team members’ learning and productivity.
A very incomplete list of CI code scanning tools includes CodeQL, Dependabot, Semgrep, Snyk, hadolint, checkov, tfsec, TruffleHog, plus the dozens of linter, formatter, and test automation tools that exist for every programming language. Setting up each of these tools is generally pretty straightforward, and they make for great “low-hanging fruit” devops tasks if you’re looking to cultivate a cross-functional team (hint, hint).
Also, if you know of any tools that I should add to this list, I’d love to learn about them! Get in touch 😺