15

Many Python modules preserve an internal state without defining classes, e.g. logging maintains several loggers accessible via getLogger().

How do you test such a module?
Using the standard unittest tools, I would like the various tests inside a TestCase class to re-import my module-under-test so that each time it loses its context. Can this be done?

Jonathan Livni
  • 101,334
  • 104
  • 266
  • 359
  • besides re-importing the module, which may be necessary in some instances, if the state you are resetting is nicely enclosed in one or a few attributes of the module, you can just use `mock.patch` to mock them out, and the mocks will be swapped out for the other tests. – C S Jun 19 '18 at 16:49

2 Answers2

17
import unittest
import sys

class Test(unittest.TestCase):
    def tearDown(self):
        try:
            del sys.modules['logging']
        except KeyError:
            pass
    def test_logging(self):
        import logging
        logging.foo=1
    def test_logging2(self):
        import logging
        print(logging.foo)

if __name__ == '__main__':
    unittest.sys.argv.insert(1,'--verbose')
    unittest.main(argv = unittest.sys.argv)    

% test.py Test.test_logging passes:

test_logging (__main__.Test) ... ok

but % test.py Test.test_logging2 does not:

test_logging2 (__main__.Test) ... ERROR

since the internal state of logging has been reset.

unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
11

This will reimport the module as new for you:

import sys
del sys.modules['my_module']
import my_module
ed.
  • 1,373
  • 8
  • 10