Ruby is a productive and fun to work with environment with lots of useful tools and products for managing software quality. Today, I am excited to share one of my recent ideas in that space: Undercover, a gem that stops us developers from shipping untested code in CI and in dev: https://github.com/grodowski/undercover.

Undercover inspects changed files and creates warnings for blocks of code which have not been tested, similar to a linter. It’s a simple idea I found useful in a large codebase along with existing coverage reporting tools and I hope you’ll see the value as well!

Testing large apps

Dealing with large inherited (legacy?) codebases carries a risk of breakage. That’s why we write tests in the first place. Every programmer is probably guilty of a bug or service outage caused by that tiny change, because it is so easy to miss a side-effect or edge case especially when we are new to a project.

But the tests, they were green!

The test suite in place may be subpar. There is no guarantee that the assumptions it makes are correct. Worst case it might not exist or be incomplete.

I have worked with such projects and used to be an advocate of always aiming for full test coverage. However, reality verified that quickly. Testing code created months or years ago by another person (who might have already left the company 😱) results in brittle tests that usually fail to capture the complexity or all edge scenarios. In other cases, it ends up becoming an endless effort of reverse engineering actual production code that works just fine for its purpose.

So is 100% test coverage actually a goal worth hitting? No, it’s usually not! I’d like to propose a different approach to measuring and improving coverage for large apps, so that we can live peacefully with legacy code and spend more time working on meaningful features.

Write tests at the right moment

Undercover is a code review utility that takes the ideas from code quality tools like RuboCop or Pronto and applies them to coverage. If 100% test coverage is not what we want to invest our time in, how about making sure that just the code in scope of our changes is tested well?

Undercover does that and triggers warnings on untested parts of our code based on a changeset from git and a set of rules. Take a look at a sample output below, where undercover checks a recent change in undercover 🙀.