DEV Community

Nick Ang
Nick Ang

Posted on

An easy way to automate running Rails test (or any command) on file changes

To my dismay, I realised today while going through unit testing in Agile Web Development with Rails 6 by Ruby, Copeland & Thomas that the Rails CLI does not ship with a --watch option.

It seems like a pretty jarring piece of missing functionality and I still don't know why it's not built into the CLI, so I posted a question in the Rails forum to ask for context, for a start. Let's see how that goes.

Jest CLI has it out of the box

Having used Jest CLI for running tests before, I was used to being able to do this:

$ jest --watchAll
Enter fullscreen mode Exit fullscreen mode

... and have the CLI handle watching files for changes and re-running relevant tests.

But as I've had to use Rails more recently, and I dug into why this was missing from the Rails CLI, I realised that "running relevant tests based on file changes" is actually quite complex. For example, if I changed a method, how should the watcher communicate to the test runner about which tests to re-run (rather than, say, re-running all tests)?

But that's a bit outside of the scope of this post. I brought it up just as a way of doing a head-nod to the complexity behind something like this.

Enter entr

Anyway, as I sat at my desk thinking about how to make my TDD-ish (test driven development) workflow easier, I realised that perhaps 50 percent of the usefulness of an automated test runner comes from re-running all tests in a particular test file if it has just been saved.

For that, I learned today that there's a nice command line package called entr that you can install with homebrew (macOS).

Here's how I used it to re-run rails tests based on changes to any file in the /test directory:

$ cd rails-app
$ find ./test -name '*.rb' | entr -s 'rails test'
Enter fullscreen mode Exit fullscreen mode

This will re-run all tests whenever any test file has been re-saved (regardless of whether an actual modification was made). A great first step!

There are gems for that

Just a quick note here that what I mentioned is just one of many ways to achieve the same thing. In fact, what I wrote is less convenient if you need to have this available to everyone in a team rather than just for yourself.

There's a video dated back to 2011 posted in RailsCast about how to use the guard gem to watch files and run tests. This is probably a better approach if you want to implement test runner automation for a team. There is a boatload of other gems that have slightly different implementations but provide similar functionality - you can see them here on ruby-toolbox.

Top comments (0)