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:
- entr, obviously. It's available in most package repositories, such as Debian and Homebrew
- The ability to run your test suite from the command line
- Nice-to-have: Fast tests
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!