Rogish Reading Writing

Companies, people, products.

Automatically Maintaining and Improving Code Quality

New software projects start the same way: clean, well-tested, and fresh in everyone’s minds. Over time, however, the knowledge fades as little-visited parts of the code aren’t touched, folks move to other projects, and new developers come on board. Test coverage drops. Mass hysteria.

Without automated, enforced quality and test coverage metrics, entropy wins and you get stuck in a vicious cycle.

We have some tools in our arsenal to help prevent code rust: we can institute code reviews, we can pair program, or folks can “lunch-n-learn” to demo code. All these are well and good, but require active effort to maintain quality. What if there were automated methods to help ensure code quality that didn’t require manual intervention?

I’m a big believer in automating all the things and code inspection is something you should strive to automate. Static code analysis allows us to enforce code standards (no spaces after parens! Two spaces, not tabs! and other holy wars), catch potential bugs or security problems, and improve code quality.

But if it’s outside of your normal day-to-day development routine you’ll forget to check it. And, like the bad old days of waterfall development, if your code gets thrown over a wall and the analysis runs long after you’ve written the code, it merely introduces more inefficiency and churn. If you integrate static code analysis into your automated testing, actual metrics prove your code is improving as you red/green/refactor.

In a Ruby/Rails project, you have several tools to help maintain code quality:

Setup

You should integrate this into your specs to run when you execute all your tests:

Rakefile
1
task default: :all_specs

and

lib/tasks/spec.rake
1
2
3
4
5
task all_specs: :environment  do
  ['rubocop -R', 'rails_best_practices', 'rspec'].each do |task|
    sh task
  end
end

Rails Best Practices

Rails Best Practices performs typical ruby checks but integrates it into a Rails environment. For example, if you have an unreachable route, it’ll report that, or report if you miss an index on a foreign key. It’s super valuable for onboarding new developers to Rails, too. Yes, they should read a Rails book, but if they inadvertently violate one of the many norms of Rails, this gem will catch it.

Rubocop

RuboCop is similar to RBP except focused on Ruby specifically. Things like spaces instead of tabs, methods and classes that are too long or complex, etc.

SimpleCov

SimpleCov allows you to lock the minimum amount of test coverage and also refuse a test coverage drop. You should define a low water line to ensure coverage does not drop below some number (90%?)

spec/spec_helper.rb
1
2
3
4
5
require 'simplecov'

SimpleCov.start 'rails'
SimpleCov.minimum_coverage 90
SimpleCov.refuse_coverage_drop

CodeClimate

CodeClimate ties these all together and has their own flavor of Ruby/Rails linters, along with JavaScript/Node.JS. CodeClimate can plug into your rspec and along with SimpleCov, report code coverage in the tool. More valuable, though, is security monitoring which reports vulnerabilities in your particular version of Ruby/Rails and when you introduce security problems in your code.

CircleCI

CircleCI is a fantastic SaaS CI provider I’ve used for a few years now. Not only are the founders super responsive, their massive parallelization functionality allows us to focus on writing code and tests and not worrying about how long they take to run.

You can combine CodeClimate and CircleCI to get test coverage reports in CC and notified of test coverage regressions in Circle.

Using all these tools, you too can have a non-trivial app that is well-tested, easy to maintain, and a joy to work with.

What tools do you use to improve the quality of your code?

software

« 30 Years of Mac How to Interview Programmers Part 2 »

Comments