From c93fbb0e57f70fe393d2d15c47978fd1e362df57 Mon Sep 17 00:00:00 2001 From: Floris Bruynooghe Date: Thu, 18 Apr 2013 12:24:53 +0100 Subject: [PATCH 1/3] Load conftest files in the correct order initially When the conftest.py files are looked for intially they got loaded starting from the subdir ending at the parent dir(s). Later on during collection any conftest.py files are loaded starting from the parent dir ending at the subdir. Due to how extending fixtures works the latter is correct as otherwise the wrong fixture will be available. So this changes the initial conftest loading to start at the root and go towards the subdir. This does also affect the order of other hooks, hence the order of the reporting being different in testing/test_terminal.py. --- _pytest/config.py | 23 +++++-------- testing/python/fixture.py | 71 +++++++++++++++++++++++++++++++++++++++ testing/test_conftest.py | 12 +++++++ testing/test_terminal.py | 2 +- 4 files changed, 92 insertions(+), 16 deletions(-) diff --git a/_pytest/config.py b/_pytest/config.py index f3c4034eb..87d3e0a2a 100644 --- a/_pytest/config.py +++ b/_pytest/config.py @@ -196,27 +196,20 @@ class Conftest(object): self.getconftestmodules(x) def getconftestmodules(self, path): - """ return a list of imported conftest modules for the given path. """ try: clist = self._path2confmods[path] except KeyError: if path is None: - raise ValueError("missing default confest.") - dp = path.dirpath() + raise ValueError("missing default conftest.") clist = [] - if dp != path: - cutdir = self._confcutdir - if cutdir and path != cutdir and not path.relto(cutdir): - pass - else: - conftestpath = path.join("conftest.py") - if conftestpath.check(file=1): - clist.append(self.importconftest(conftestpath)) - clist[:0] = self.getconftestmodules(dp) + for parent in path.parts(): + if self._confcutdir and self._confcutdir.relto(parent): + continue + conftestpath = parent.join("conftest.py") + if conftestpath.check(file=1): + clist.append(self.importconftest(conftestpath)) self._path2confmods[path] = clist - # be defensive: avoid changes from caller side to - # affect us by always returning a copy of the actual list - return clist[:] + return clist def rget(self, name, path=None): mod, value = self.rget_with_confmod(name, path) diff --git a/testing/python/fixture.py b/testing/python/fixture.py index 02cd55c21..891871c0f 100644 --- a/testing/python/fixture.py +++ b/testing/python/fixture.py @@ -102,6 +102,77 @@ class TestFillFixtures: "*2 passed*" ]) + def test_extend_fixture_module_class(self, testdir): + testfile = testdir.makepyfile(""" + import pytest + + @pytest.fixture + def spam(): + return 'spam' + + class TestSpam: + + @pytest.fixture + def spam(self, spam): + return spam * 2 + + def test_spam(self, spam): + assert spam == 'spamspam' + """) + result = testdir.runpytest() + result.stdout.fnmatch_lines(["*1 passed*"]) + result = testdir.runpytest(testfile) + result.stdout.fnmatch_lines(["*1 passed*"]) + + def test_extend_fixture_conftest_module(self, testdir): + testdir.makeconftest(""" + import pytest + + @pytest.fixture + def spam(): + return 'spam' + """) + testfile = testdir.makepyfile(""" + import pytest + + @pytest.fixture + def spam(spam): + return spam * 2 + + def test_spam(spam): + assert spam == 'spamspam' + """) + result = testdir.runpytest() + result.stdout.fnmatch_lines(["*1 passed*"]) + result = testdir.runpytest(testfile) + result.stdout.fnmatch_lines(["*1 passed*"]) + + def test_extend_fixture_conftest_conftest(self, testdir): + testdir.makeconftest(""" + import pytest + + @pytest.fixture + def spam(): + return 'spam' + """) + pkg = testdir.mkpydir("pkg") + pkg.join("conftest.py").write(py.code.Source(""" + import pytest + + @pytest.fixture + def spam(spam): + return spam * 2 + """)) + testfile = pkg.join("test_spam.py") + testfile.write(py.code.Source(""" + def test_spam(spam): + assert spam == "spamspam" + """)) + result = testdir.runpytest() + result.stdout.fnmatch_lines(["*1 passed*"]) + result = testdir.runpytest(testfile) + result.stdout.fnmatch_lines(["*1 passed*"]) + def test_funcarg_lookup_error(self, testdir): p = testdir.makepyfile(""" def test_lookup_error(unknown): diff --git a/testing/test_conftest.py b/testing/test_conftest.py index 6b9689fe3..6f8cea588 100644 --- a/testing/test_conftest.py +++ b/testing/test_conftest.py @@ -204,3 +204,15 @@ def test_conftest_confcutdir(testdir): """)) result = testdir.runpytest("-h", "--confcutdir=%s" % x, x) result.stdout.fnmatch_lines(["*--xyz*"]) + +def test_conftest_import_order(testdir, monkeypatch): + ct1 = testdir.makeconftest("") + sub = testdir.mkdir("sub") + ct2 = sub.join("conftest.py") + ct2.write("") + def impct(p): + print p + return p + conftest = Conftest() + monkeypatch.setattr(conftest, 'importconftest', impct) + assert conftest.getconftestmodules(sub) == [ct1, ct2] diff --git a/testing/test_terminal.py b/testing/test_terminal.py index e6977c457..5054ac398 100644 --- a/testing/test_terminal.py +++ b/testing/test_terminal.py @@ -643,9 +643,9 @@ def pytest_report_header(config, startdir): """) result = testdir.runpytest("a") result.stdout.fnmatch_lines([ + "*hello: 42*", "line1", str(testdir.tmpdir), - "*hello: 42*", ]) @pytest.mark.xfail("not hasattr(os, 'dup')") From ea7a997afc24ad3081932912a3905556008a126f Mon Sep 17 00:00:00 2001 From: Anatoly Bubenkov Date: Sat, 6 Jul 2013 10:26:14 +0200 Subject: [PATCH 2/3] remove unnecessary print --- testing/test_conftest.py | 1 - 1 file changed, 1 deletion(-) diff --git a/testing/test_conftest.py b/testing/test_conftest.py index 6f8cea588..d753f5672 100644 --- a/testing/test_conftest.py +++ b/testing/test_conftest.py @@ -211,7 +211,6 @@ def test_conftest_import_order(testdir, monkeypatch): ct2 = sub.join("conftest.py") ct2.write("") def impct(p): - print p return p conftest = Conftest() monkeypatch.setattr(conftest, 'importconftest', impct) From 1a319056fcc72e245a1cc4c7a942f18536e4d6ac Mon Sep 17 00:00:00 2001 From: Floris Bruynooghe Date: Sat, 6 Jul 2013 11:00:29 +0200 Subject: [PATCH 3/3] Mention issue 300 in changelog --- CHANGELOG | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index a2a129fde..7c4c983d2 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,9 @@ Changes between 2.3.5 and 2.4.DEV ----------------------------------- +- fix issue300 - Fix order of conftest loading when starting py.test + in a subdirectory. + - fix issue323 - sorting of many module-scoped arg parametrizations - add support for setUpModule/tearDownModule detection, thanks Brian Okken.