Skip to content

Instantly share code, notes, and snippets.

@eenblam
Last active October 25, 2016 21:08
Show Gist options
  • Save eenblam/c294d9fd49772ed5cb7c to your computer and use it in GitHub Desktop.
Save eenblam/c294d9fd49772ed5cb7c to your computer and use it in GitHub Desktop.
quick autotesting with pyinotify

Inspired by Building robust software in Python using unit tests. I didn't want to bother with fswatch, and I found a similar script in the pyinotify wiki.

With the included Makefile, you can just run make dev_test, and your tests will execute whenever you make an edit! Better for the early stages of a TDD project.

Note that you can add more than just .py files. autotest.py ~/path/to/project .py,.js,.html "clear && make tests" will run your test suite whenever you create, delete, or edit a file with a .py, .js, or.html extension.

#!/usr/bin/env python
# Sourced, with some modification, from
# https://github.com/seb-m/pyinotify/blob/master/python2/examples/autocompile.py
import subprocess
import sys
import pyinotify
class OnWriteHandler(pyinotify.ProcessEvent):
def my_init(self, cwd, extension, cmd):
self.cwd = cwd
self.extensions = extension.split(',')
self.cmd = cmd
def _run_cmd(self):
print('==> Modification detected')
#subprocess.call(self.cmd.split(' '), cwd=self.cwd)
subprocess.call(self.cmd, cwd=self.cwd, shell=True)
def process_IN_MODIFY(self, event):
if all(not event.pathname.endswith(ext) for ext in self.extensions):
return
self._run_cmd()
def process_IN_CREATE(self, event):
self.process_IN_MODIFY(event)
def process_IN_DELETE(self, event):
self.process_IN_MODIFY(event)
def process_IN_MOVED_TO(self, event):
self.process_IN_MODIFY(event)
def process_IN_MOVED_FROM(self, event):
self.process_IN_MODIFY(event)
def auto_compile(path, extension, cmd):
wm = pyinotify.WatchManager()
handler = OnWriteHandler(cwd=path, extension=extension, cmd=cmd)
notifier = pyinotify.Notifier(wm, default_proc_fun=handler)
wm.add_watch(path, pyinotify.ALL_EVENTS, rec=True, auto_add=True)
print('==> Start monitoring {} (type c^c to exit)'.format(path))
notifier.loop()
if __name__ == '__main__':
if len(sys.argv) < 3:
print("Command line error: missing argument(s).", file=sys.stderr)
sys.exit(1)
# Required arguments
path = sys.argv[1]
extension = sys.argv[2]
# Optional argument
cmd = 'make'
if len(sys.argv) == 4:
cmd = sys.argv[3]
# Blocks monitoring
auto_compile(path, extension, cmd)
tests:
nose2
dev_test:
autotest.py ~/path/to/project .py "clear && make tests"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment