Martin Polden

Immediate test feedback with entr

When writing code I like receiving feedback from unit tests as quickly as possible. Recently, I've been writing some Go code and decided to try entr for running tests automatically. entr is tool that runs arbitrary commands when a monitored file changes.

Prerequisites for this workflow:

Example

Consider the following Go source files:

$ ls
foo.go  foo_test.go  go.mod

To continuously test this code with entr, we can do:

$ find . -name '*.go' -type f | entr -c go test

# or if it's a git repository:
$ git ls-files -co '*.go' | entr -c go test

Whenever a .go file changes, entr will clear the screen (the -c option) and run go test. Since both compilation and test-running in Go is very fast, my tests usually complete in the time it takes me to switch from Emacs to my terminal.

Working around ghost files

When working with a Git repository, a watched source file may disappear and reappear when switching and merging branches. Continuing from the example above, we create a new branch and add additional files:

$ git checkout -b develop
# create bar.go and bar_test.go
$ git ls-files -co '*.go' | entr -c go test

We then commit these new files and switch back to the master branch:

$ git add bar*.go && git commit -m 'add bar'
$ git checkout master

entr will then exit, because a watched file disappears when we switch branches:

entr: cannot open 'bar.go': Operation timed out

Luckily we can work around this by running entr in a simple loop:

while true; do git ls-files -co '*.go' | entr -c go test; done

Conclusion

While file system events can be notoriously fiddly and hard to get right, entr mostly succeeds in hiding these underlying complexities. With entr I was able to automatically run tests on code changes and thus receive immediate feedback.

Mission accomplished!

Date: 2021-09-29 Wed 19:39

Author: Martin Polden