Adam Haney

I'm an entrepreneur and hacker living in #cha. Working on a few different projects. You can find me on github, twitter and angel list.

Sitemap •  RSS Feed

Running Tests When Files Change on OS X

Nov. 29, 2015

The Problem

Recently I was working on a Django project and I wanted to have my unit tests run whenever any file in my project directory changed. My assumption was that if I had my tests running continuously in a terminal while I was editing code I would be less likely to create tests that took a long time to run and I'd be more productive because I wouldn't constantly be running "python manage.py test". 

Existing "Solutions"

Upon scouring the internet I found a few existing packages that claim to do what I want. The python based solutions PyZen, Nose-watch both have bugs that I couldn't overcome. Pyzen hasn't gotten an update in almost 3 years and Nose-watch doesn't play nice with custom test runners in Django. Beyond this watching the filesystem for changes and running a command falls squarely in the "unix should solve this problem" camp in my opinion. This is the type of problem that shouldn't really be a framework concern.

The Solution That worked for me

I really wanted to solve this problem using an existing cli tool that could watch a directory. This is the kind of problem that inotify would solve well in the unix world, but I was developing on a MacBook Air and I didn't want to set up a Vagrant environment just to run my tests (I'll probably do this eventually but I was working on a hobby project where development / product environment parity isn't strictly essential). I found an excellent Stack Overflow answer (http://stackoverflow.com/questions/1515730/is-there-a-command-like-watch-or-inotifywait-on-the-mac) that suggested the fswatch for watching filesystems on OS X. After a bit of fiddling the following command worked for me and allowed me to have my tests run whenever I change a file in my project:

fswatch -r . -e ".*#.*" -e ".*\.pyc" -o | xargs -n1 -I{} python manage.py test

The -e flags exclude any paths matching the regular expression. I'm using emacs and found that the autosave files caused tests to run more frequently than needed. I'm also excluding changes to .pyc files because they typically change right after .py files are changes (especially if you're also running the development server which will trigger .pyc files to be created on file change about 2 seconds after a .py file is changed) excluding these files stops tests from being run twice on each change. I hope this command saves you some time when you're working on testing your next project. 

Next entry

Previous entry:

comments powered by Disqus