diff --git a/_pytest/monkeypatch.py b/_pytest/monkeypatch.py index fe54e63af..c2d27ff33 100644 --- a/_pytest/monkeypatch.py +++ b/_pytest/monkeypatch.py @@ -30,6 +30,7 @@ class monkeypatch: def __init__(self): self._setattr = [] self._setitem = [] + self._cwd = None def setattr(self, obj, name, value, raising=True): """ set attribute ``name`` on ``obj`` to ``value``, by default @@ -83,6 +84,14 @@ class monkeypatch: self._savesyspath = sys.path[:] sys.path.insert(0, str(path)) + def chdir(self, path): + if self._cwd is None: + self._cwd = os.getcwd() + if hasattr(path, "chdir"): + path.chdir() + else: + os.chdir(path) + def undo(self): """ undo previous changes. This call consumes the undo stack. Calling it a second time has no effect unless @@ -105,3 +114,7 @@ class monkeypatch: if hasattr(self, '_savesyspath'): sys.path[:] = self._savesyspath del self._savesyspath + + if self._cwd is not None: + os.chdir(self._cwd) + self._cwd = None diff --git a/testing/test_monkeypatch.py b/testing/test_monkeypatch.py index 8ec7e1b23..03a6f703b 100644 --- a/testing/test_monkeypatch.py +++ b/testing/test_monkeypatch.py @@ -172,3 +172,24 @@ def test_syspath_prepend_double_undo(mp): sys.path.append('more hello world') mp.undo() assert sys.path[-1] == 'more hello world' + +def test_chdir_with_path_local(mp, tmpdir): + mp.chdir(tmpdir) + assert os.getcwd() == tmpdir.strpath + +def test_chdir_with_str(mp, tmpdir): + mp.chdir(tmpdir.strpath) + assert os.getcwd() == tmpdir.strpath + +def test_chdir_undo(mp, tmpdir): + cwd = os.getcwd() + mp.chdir(tmpdir) + mp.undo() + assert os.getcwd() == cwd + +def test_chdir_double_undo(mp, tmpdir): + mp.chdir(tmpdir.strpath) + mp.undo() + tmpdir.chdir() + mp.undo() + assert os.getcwd() == tmpdir.strpath