views:

44

answers:

1

I'm using pyinotify to mirror files from a source directory to a destination directory. My code seems to be working when I execute it manually, but I'm having trouble getting accurate unit test results. I think the problem boils down to this:

  1. I have to use ThreadedNotifier in my tests, otherwise they will just hang, waiting for manual input.
  2. Because I'm using another thread, my tests and the Notifier get out of sync. Tests that pass when running observational, manual tests fail when running the unit tests.

Has anyone succeeded in unit testing pyinotify?

+3  A: 

When unit testing, things like threads and the file system should normally be factored out. Do you have a reason to unit test with the actual file system, user input, etc.?

Python makes it very easy to monkey patch; you could for example, replace the entire os/sys module with a mock object (such as Python Mock) so that you never need to deal with the file system. This will also make your tests run much more quickly.

If you want to do functional testing with the file system, I'd recommend setting up a virtual machine that will have a known state, and reverting to that state every time you run the tests. You could also simulate user input, file operations, etc. as needed.

Edit

Here's a simple example of how to fake, or mock the "open" function.

Say you've got a module, my_module, with a get_text_upper function:

def get_text_upper(filename):
    return open(filename).read().upper()

You want to test this without actually touching the file system (eventually you'll start just passing file objects instead of file names to avoid this but for now...). You can mock the open function so that it returns a StringIO object instead:

from cStringIO import StringIO

def fake_open(text):
    fp = StringIO()
    fp.write(text)
    fp.seek(0)
    return fp

def test_get_text():
    my_module.open = lambda *args, **kwargs : fake_open("foo")
    text = my_module.get_text_upper("foo.txt")
    assert text == "FOO", text

Using a mocking library just makes this process a lot easier and more flexible.

Here's a stackoverflow post on mocking libraries for python.

Ryan Ginstrom
Mocking is something I haven't delved into, but I may be crossing that road now. Aside from the link above, are there any other good resources for learning mocks conceptually?
Wraith