Skip to content

pytester: use monkeypatch with Testdir #5031

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog/5031.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Environment variables are properly restored when using pytester's ``testdir`` fixture.
22 changes: 13 additions & 9 deletions src/_pytest/pytester.py
Original file line number Diff line number Diff line change
Expand Up @@ -476,9 +476,6 @@ def __init__(self, request, tmpdir_factory):
name = request.function.__name__
self.tmpdir = tmpdir_factory.mktemp(name, numbered=True)
self.test_tmproot = tmpdir_factory.mktemp("tmp-" + name, numbered=True)
os.environ["PYTEST_DEBUG_TEMPROOT"] = str(self.test_tmproot)
os.environ.pop("TOX_ENV_DIR", None) # Ensure that it is not used for caching.
os.environ.pop("PYTEST_ADDOPTS", None) # Do not use outer options.
self.plugins = []
self._cwd_snapshot = CwdSnapshot()
self._sys_path_snapshot = SysPathsSnapshot()
Expand All @@ -491,6 +488,13 @@ def __init__(self, request, tmpdir_factory):
elif method == "subprocess":
self._runpytest_method = self.runpytest_subprocess

mp = self.monkeypatch = MonkeyPatch()
mp.setenv("PYTEST_DEBUG_TEMPROOT", str(self.test_tmproot))
# Ensure no unexpected caching via tox.
mp.delenv("TOX_ENV_DIR", raising=False)
# Discard outer pytest options.
mp.delenv("PYTEST_ADDOPTS", raising=False)

def __repr__(self):
return "<Testdir %r>" % (self.tmpdir,)

Expand All @@ -508,7 +512,7 @@ def finalize(self):
self._sys_modules_snapshot.restore()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While at it, would you like to replace those "snapshot" implementations by your monkeypatch instance?

If not, please go ahead and merge it as this is already an improvement

(every time I looked at this code I had the same idea to use monkeypatch for that, but kept forgetting to actually do it 🙃)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really now - basically got side-tracked by this already for #5032.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

btw: to me it looked just like code that could be improved, assuming that os.environ would get restored, but that's actually not the case.. therefore targetting master.

self._sys_path_snapshot.restore()
self._cwd_snapshot.restore()
os.environ.pop("PYTEST_DEBUG_TEMPROOT", None)
self.monkeypatch.undo()

def __take_sys_modules_snapshot(self):
# some zope modules used by twisted-related tests keep internal state
Expand Down Expand Up @@ -799,11 +803,11 @@ def inline_run(self, *args, **kwargs):
"""
finalizers = []
try:
# Do not load user config.
monkeypatch = MonkeyPatch()
monkeypatch.setenv("HOME", str(self.tmpdir))
monkeypatch.setenv("USERPROFILE", str(self.tmpdir))
finalizers.append(monkeypatch.undo)
# Do not load user config (during runs only).
mp_run = MonkeyPatch()
mp_run.setenv("HOME", str(self.tmpdir))
mp_run.setenv("USERPROFILE", str(self.tmpdir))
finalizers.append(mp_run.undo)

# When running pytest inline any plugins active in the main test
# process are already imported. So this disables the warning which
Expand Down
13 changes: 13 additions & 0 deletions testing/test_pytester.py
Original file line number Diff line number Diff line change
Expand Up @@ -469,3 +469,16 @@ def test_linematcher_with_nonlist():

assert lm._getlines({}) == {}
assert lm._getlines(set()) == set()


def test_pytester_addopts(request, monkeypatch):
monkeypatch.setenv("PYTEST_ADDOPTS", "--orig-unused")

testdir = request.getfixturevalue("testdir")

try:
assert "PYTEST_ADDOPTS" not in os.environ
finally:
testdir.finalize()

assert os.environ["PYTEST_ADDOPTS"] == "--orig-unused"