From bc0ecd1d0619fa39ac995bb1bcc5c89a150cf7d6 Mon Sep 17 00:00:00 2001 From: Eduardo Schettino Date: Tue, 21 Apr 2015 10:18:04 +0800 Subject: [PATCH] pytester: add method ``TmpTestdir.delete_loaded_modules()`` , and call it from ``inline_run()`` to allow temporary modules to be reloaded. --HG-- branch : pytester-inline-run-clean-sys-modules --- AUTHORS | 1 + CHANGELOG | 2 ++ _pytest/pytester.py | 13 +++++++++++-- testing/test_pytester.py | 11 +++++++++++ 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/AUTHORS b/AUTHORS index abe29c261..f556c50da 100644 --- a/AUTHORS +++ b/AUTHORS @@ -48,3 +48,4 @@ Nicolas Delaby Tom Viner Dave Hunt Charles Cloud +schettino72 diff --git a/CHANGELOG b/CHANGELOG index 90f426ad7..1114ad0a6 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,8 @@ 2.8.0.dev (compared to 2.7.X) ----------------------------- +- pytester: add method ``TmpTestdir.delete_loaded_modules()``, and call it + from ``inline_run()`` to allow temporary modules to be reloaded. 2.7.1.dev (compared to 2.7.0) ----------------------------- diff --git a/_pytest/pytester.py b/_pytest/pytester.py index 1ab7ba2c6..e21dc10ff 100644 --- a/_pytest/pytester.py +++ b/_pytest/pytester.py @@ -266,7 +266,7 @@ class TmpTestdir: Some methods modify the global interpreter state and this tries to clean this up. It does not remove the temporary - directlry however so it can be looked at after the test run + directory however so it can be looked at after the test run has finished. """ @@ -274,7 +274,15 @@ class TmpTestdir: sys.path.remove(p) if hasattr(self, '_olddir'): self._olddir.chdir() - # delete modules that have been loaded from tmpdir + self.delete_loaded_modules() + + def delete_loaded_modules(self): + """Delete modules that have been loaded from tmpdir. + + This allows the interpreter to catch module changes in case + the module is re-imported. + + """ for name, mod in list(sys.modules.items()): if mod: fn = getattr(mod, '__file__', None) @@ -539,6 +547,7 @@ class TmpTestdir: assert len(rec) == 1 reprec = rec[0] reprec.ret = ret + self.delete_loaded_modules() return reprec def parseconfig(self, *args): diff --git a/testing/test_pytester.py b/testing/test_pytester.py index ac57f2c87..d69809c94 100644 --- a/testing/test_pytester.py +++ b/testing/test_pytester.py @@ -2,6 +2,8 @@ import pytest import os from _pytest.pytester import HookRecorder from _pytest.core import PluginManager +from _pytest.main import EXIT_OK, EXIT_TESTSFAILED + def test_make_hook_recorder(testdir): item = testdir.getitem("def test_func(): pass") @@ -121,3 +123,12 @@ def test_inprocess_plugins(testdir): testdir.inprocess_run([], [plugin]) assert plugin.configured + +def test_inline_run_clean_modules(testdir): + test_mod = testdir.makepyfile("def test_foo(): assert True") + result = testdir.inline_run(str(test_mod)) + assert result.ret == EXIT_OK + # rewrite module, now test should fail if module was re-imported + test_mod.write("def test_foo(): assert False") + result2 = testdir.inline_run(str(test_mod)) + assert result2.ret == EXIT_TESTSFAILED