Keeping your Nose Green
Posted by Jeff April 27, 2006
Mark of pywinauto fame told me about nose, a unit testing tool with autodiscovery. I was slinging some python over the weekend, and needed coverage as my codebase got bigger.. so I whipped this up. I run this on a DOS window under windows. Basically every time you change any .py file, it runs tests. I call it nosy. (nosy.py)
import glob,os,stat,time
def checkSum():
‘'’ Return a long which can be used to know if any .py files have changed.
Only looks in the current directory. ‘'’
val = 0
for f in glob.glob (’*.py’):
stats = os.stat (f)
val += stats [stat.ST_SIZE] + stats [stat.ST_MTIME]
return valval=0
while (True):
if checkSum() != val:
val=checkSum()
os.system (’nosetests’)
time.sleep(1)
A screencast is up at ShowMeDo. I’ve sent it to Jason for improvement.
Update: Windows Installer for Nosy.
Great idea! I had a go at doing the same thing with eclipse and it turns out to be easy. Just set nose up as a auto builder. If anyyones interested, I describe the process in more detail here: http://www.machine-envy.com/blog/?p=45
Thanks for the cool script. One suggestion (maybe it’s already being handled by integrating with Nose): if your tests are in a different directory (e.g. ./tests/) than the directory nosy is running from it will not register and run the tests again. I patched my nosy.py to look in both directories, but it’d be cool if it had the same auto discovery magic that Nose does. Thanks!
This is great. I think it will help me convince the company to use more python. Thanks!
Here is a checkSum function that monitors the python code in the directory where nosy.py was started as well as any subdirectories under that one:
def checkSumRecurse():
val = 0
for dirpath, dirs, files in os.walk(”.”):
for file in [file for file in files if file[-3:]==”.py”]:
absoluteFileName = os.path.join( dirpath, file)
stats = os.stat(absoluteFileName)
val += stats [stat.ST_SIZE] + stats [stat.ST_MTIME]
return val
Jeff, this is a terrific tool. Simple, yet sooooo, handy. Thank you for creating and sharing it.
The Windows installer did not seem to work for me. No matter where I placed it, it said it couldn’t find C:\Python25\Scripts\nosetests.exe, which looks like it’s where it ought to be. So I copied nosy.py to the Scripts directory and wrote a nosy.bat file to start it.
Am I correct that it needs to be started from the directory where the scripts to be checked are located, and not in a directory above? Since I think nose checks subdirectories, at first I assumed that nosy would do the same and started it from the directory above the one with the scripts, but it didn’t seem to detect the changes in the subdirectory. When I executed the command from the directory with the scripts, it worked like a charm.
Nose with nosy is so cool I have overcome my resistance to trying unit test driven development. Now that’s really something. If nosy does the same thing for some *real* programmers, you will have made the world a slightly better place. Congratulations.
This doesn’t appear to work on ubuntu linux. Any chance you could try a port? I would do it myself, but after trying a few things I gave up, as my knowledge of the OS processes is rather limited.
In short, it launches nosetests an ever-growing number of times until it crashes your system. I tried getting it to wait until the previous call had completed, but I didn’t succeed.
Very cool tool, Jeff! I’ve wanted something like this since I started using nose a few months ago, but never came up with a good way of monitoring the source files for changes. Your checksum method is so simple and elegant.
I used nosy a bit, decided I needed it to be more flexible, tweaked it a bit, liked the result, and then got really carried away… The result is a version that can take a command line option to point it at a config file. The config file can supply the paths to glob and check of source file changes, command line options to pass to nose, and command line args for nose (like specific tests to run). I also did some compulsive PEP8-ification.
My version is at http://douglatornell.ca/software/python/nosy/nosy.py and there’s a sample config file at http://douglatornell.ca/software/python/nosy/sample.cfg
I’ve been putting nosy.cfg in the tests/ directory or my projects and invoking nosy with nosy -c tests/nosy.cfg.
There are undoubtedly bugs in my version - I’ve only been using it a few hours. I’ll dogfood it at work next week
Hope you don’t mind me riffing on your idea…
There are alternative ways to monitor files that may be needed to scale up this technique. On UNIX there is FAM (File Alteration Monitor).
http://python-fam.sourceforge.net/
On Windows, two techiques beyond that of nosy are give here:
http://tgolden.sc.sabren.com/python/win32_how_do_i/watch_directory_for_changes.html
Handy script you have, thanks.
I just set this up to work with my unittest.TestSuite based setup.
There is an error in Windows installer - Nosy cann’t be installed…
I noticed that the root of the problem is in “installer.nsi” script for creating .exe file: namely, in line 28 (IfFileExists $1Scripts\nosetests.exez NOSEINSTALLED) .nsi file that I mention, there is error (probably issued like consequence of typing), “.exez” must be “.exe”!!!
I solved my problem on mine machine, but it will be very nice if “somebody” fixed this for other people who uses this installer…
Btw, thanks for this great tool…
Regards,
Stole
I recommend adding the following line to the nosy script:
win: os.system(’cls’)
linux: os.system(’clear’)
Ofc this is a matter of taste but I prefer to see every tests run in a cleared screen.