6

Related to Python unit testing code which calls OS/Module level python functions. During my unit testing I overload some python system calls to get my tests to drive different paths of a module. This technique called Monkey Patch (in the related question) for tests in isolation.

I am a bit worried about what happens when I run Python tests in parallel say like in "Nose". What happens when two tests are run in parallel and both want to mock the os.path.exists method?

Is there a way to selectively override a system or module function in the context of my test?

Take the following for example

fixture.py (say that is the module under test)

def my_func():
    some_stuff

test_fixture.py (say this is my test case)


class MyTest(unittest.TestCase):

    def test_mine(self):
         fixture.my_func = my_new_func
         fixture.execute_some_func_that_calls_my_func()
         #What happens if another test is executing at the same time and accesses
         #my_func I don't want it to start executing my_new_func?
Community
  • 1
  • 1
Kannan Ekanath
  • 16,759
  • 22
  • 75
  • 101

1 Answers1

4

I don't know if it's the best way, but I generally use try ... finally when I'm doing this in tests, in order to set then restore changes during each test.

A brief example of this:

class TestRawInput(unittest.TestCase):

    def test_raw_input(self):
        orig_raw_input = raw_input
        try:
            raw_input = lambda _: 'Alice'
            self.assertEquals(raw_input(), 'Alice')
        finally:
            raw_input = orig_raw_input

An alternative could be to create a context manager for doing this, if it's a common operation in tests.

Dave Challis
  • 3,525
  • 2
  • 37
  • 65
  • what is the name_getter here? Is it the module where the class TestNameGetter resides? – Kannan Ekanath Apr 24 '13 at 10:34
  • Yes, sorry, I was using the answer at http://stackoverflow.com/questions/14956825/python-unit-testing-code-which-calls-os-module-level-python-functions as an example. Let me update my example to be clearer. – Dave Challis Apr 24 '13 at 10:40
  • Ya so what happens when TWO tests are executing in parallel that hit the same name_getter module and if both want different raw_input functions? Does this still work? – Kannan Ekanath Apr 24 '13 at 10:42
  • 1
    Yes, it should still work. Nose uses separate processes to execute tests in parallel, so changes to a function/module in one won't affect the other. – Dave Challis Apr 24 '13 at 10:48