Will Your Review Bot Actually Catch the Bugs?
Here's a number that should stop you cold: at Google, fewer than 25% of code changes have more than one reviewer, and the median change size is just 24 lines (Modern Code Review: A Case Study at Google, ICSE-SEIP '18). That means your human review is almost always a single pair of eyes on a tiny diff. But here's the uncomfortable truth: that pair of eyes is not primarily looking for bugs. The same study found that 97% of developers are satisfied with their review tool, yet the four key expectations of review are education, maintaining norms, gatekeeping, and accident prevention—not defect detection. So if we're honest, the bot isn't just a helper; it's often the only systematic check for bugs we've got.
That's why I'm a zealot about automated quality gates. But not just any gate. I want you to set your quality gate to require 80% test coverage on new code. And I'm not pulling that number out of thin air—it's the threshold that SonarQube's own built-in 'Sonar way' quality gate uses, alongside a 3% duplication limit on new code. If the tool that's been analyzing code for millions of developers thinks 80% is the bar, I think you should listen.
What Does an 80% Gate Actually Do to Your Review?
An 80% coverage gate forces a conversation. When your pull request shows 60% coverage, the bot blocks the merge. The author has to either write more tests or explain why those lines are untestable. That's the gate's real power: it makes the implicit explicit. Without a gate, a reviewer might glance at a diff and say, 'Looks fine, but could you add a test for this edge case?'—and that comment often gets lost in the noise. With a gate, the CI fails, the PR is red, and the discussion is focused.
But here's the nuance: I'm not talking about overall coverage. I'm talking about coverage on new code. SonarQube's quality gate checks new code coverage, not the whole codebase. That's a crucial distinction. You can't fix years of technical debt overnight, and you shouldn't try. What you can do is ensure that every line you add today is tested. Over time, that's how you build a codebase that's actually safe to change.
Why 80% and Not 100%?
Because 100% coverage is a lie. It gives you a false sense of security while making your tests brittle. The fact base is clear: SonarQube defines test coverage as a metric, but it also defines cognitive complexity and cyclomatic complexity—metrics that measure how hard code is to understand. If you chase 100% coverage, you'll end up writing tests that assert implementation details, not behavior. They'll break every time you refactor, and you'll start hating your test suite.
Eighty percent is a sweet spot. It's high enough to force you to test most of your logic, but low enough that you don't have to write contrived tests for getters, setters, or UI glue. And remember, the gate is on new code, so it's not asking you to retrofit tests on legacy spaghetti. It's asking you to do better going forward. That's a reasonable ask.
But Wait—Doesn't This Slow Us Down?
I've heard the objection a hundred times: 'We don't have time to write tests, we need to ship faster.' But the research says the opposite. Google's own guidance on small changes is explicit: small CLs are reviewed more quickly, more thoroughly, and are less likely to introduce bugs. And what's the median size of a Google change? 24 lines. That's not a coincidence. When you keep changes small, writing 80% coverage is a matter of minutes, not days.
And here's the kicker from the DORA metrics: speed and stability are not tradeoffs. DORA's research has repeatedly shown that top performers do well on all five metrics—change lead time, deployment frequency, failed deployment recovery time, change fail rate, and deployment rework rate. They don't sacrifice quality for speed. They achieve both because they have safety nets. An automated coverage gate is a safety net. It catches the bug before it reaches production, so you don't have to spend hours recovering from a failed deployment.
Let me give you a concrete example. Say you're reviewing a 200-line change across 50 files. That's a red flag right there—Google says 100 lines is usually reasonable, 1000 is too large, and a 200-line change across 50 files is usually too large. But let's say it's a new feature. With an 80% gate, the author has to write tests for the new logic. If they can't get coverage above 50%, that's a signal to you, the reviewer, that either the code is poorly structured or the tests are missing. You can dig in and ask why. Without a gate, you might approve it and move on, only to discover a null pointer exception in production two weeks later.
What About Security? Don't Forget the Bots That Scan for Vulnerabilities
Coverage is only half the story. The other half is security. OWASP's Top 10 for 2025 puts Broken Access Control at #1, with SSRF rolled into that category. Injection is at #5. These are the kinds of bugs that a human reviewer might miss, especially under time pressure. That's why you need static analysis tools that run automatically. Tools like Semgrep, Bandit, and gosec are designed to catch these patterns. Bandit, for example, builds an AST from your Python code and runs plugins to find common security issues. gosec does taint analysis for SQL injection, command injection, path traversal, SSRF, XSS, and unsafe deserialization. These aren't optional extras; they're your first line of defense.
And don't forget dependency scanning. GitHub's Dependabot scans your default branch and alerts you when a new vulnerability is added to the GitHub Advisory Database. But here's a limitation: it can't catch every issue, and archived repositories aren't scanned. So it's not a silver bullet, but it's a necessary part of your automated review stack.
My recommendation is to set up a multi-layer bot: a linter (like ESLint), a security scanner (like Semgrep), a dependency scanner (like Dependabot), and a quality gate (like SonarQube). But don't try to do it all at once. Start with the coverage gate, because it's the one that forces the most behavioral change. Then add security scanning. Then add dependency scanning.
But What About the Human? The Bot Can't Replace the Reviewer
Let me be clear: I'm not saying the bot replaces the human. In fact, the research from Bacchelli and Bird at Microsoft found that while finding defects is the main motivation for code review, the reality is that reviews provide additional benefits like knowledge transfer and team awareness. The bot can't do that. Only a human can say, 'Hey, I don't understand this logic, can you explain it?' And when a reviewer says that, Google's advice is to clarify the code itself, not just answer in the review thread.
So the bot's job is to handle the mechanical checks—style, complexity, coverage, security—so the human can focus on the design and architecture. That's exactly what Google's engineering practices say: linters, formatters, static analysis, secret scanners, and dependency scanners should handle the mechanical checks so human review focuses on logic and architecture. And when you do that, reviews get faster. Google's data shows that the median time to first feedback is under 1 hour for small changes. That's because the bot has already done the tedious work.
But there's a danger: if you set the gate too strict, you'll create friction. For instance, if you require 100% coverage, you'll have developers gaming the system with dummy tests. Or if you require a specific number of approvals and you have a bot that auto-approves, you'll get a rubber stamp. That's why I'm specific about the 80% gate on new code. It's a meaningful bar that's achievable with good practices.
The One Thing to Remember
The most important thing to remember is that your automated quality gate should set a floor, not a ceiling. It's there to catch the things humans miss, but it's not there to make the code perfect. As Google's senior review principle says, 'there is no such thing as perfect code, there is only better code.' So set your gate to 80% coverage, let your bots do their mechanical work, and then spend your human review time on the design, the edge cases, and the knowledge sharing. That's how you build a codebase that improves over time.
Sources
- Modern Code Review: A Case Study at Google (ICSE-SEIP '18) - https://www.papercache.org/papers/mlsys/system/2026/03/25/modern-code-review-a-case-study-at-google
- SonarQube Server Docs - Understanding quality gates - https://docs.sonarsource.com/sonarqube-server/2026.1/quality-standards-administration/managing-quality-gates/introduction-to-quality-gates
- Google Engineering Practices - Speed of Code Reviews - https://google.github.io/eng-practices/review/reviewer/speed.html
- Google Engineering Practices - Small CLs - https://google.github.io/eng-practices/review/developer/small-cls.html
- DORA - Software delivery performance metrics - https://dora.dev/guides/dora-metrics-four-keys/
- OWASP Top Ten 2025 - https://owasp.org/Top10/2025/0x00_2025-Introduction/
Comments (0)
Please sign in to post a comment.
Don't have an account? Create one
No comments yet. Be the first to comment!