From 4d3c1ab4f09ad352b9b0a274f0d802826771e4ed Mon Sep 17 00:00:00 2001 From: turturica Date: Wed, 22 Aug 2018 21:42:59 -0700 Subject: [PATCH] Fixes #3854 --- src/_pytest/python.py | 15 ++++++++++----- testing/python/collect.py | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/src/_pytest/python.py b/src/_pytest/python.py index 51bc28fe5..891e071c6 100644 --- a/src/_pytest/python.py +++ b/src/_pytest/python.py @@ -590,18 +590,23 @@ class Package(Module): self.session.config.pluginmanager._duplicatepaths.remove(path) this_path = self.fspath.dirpath() - pkg_prefix = None - yield Module(this_path.join("__init__.py"), self) + pkg_prefixes = set() for path in this_path.visit(rec=self._recurse, bf=True, sort=True): # we will visit our own __init__.py file, in which case we skip it + skip = False if path.basename == "__init__.py" and path.dirpath() == this_path: continue - if pkg_prefix and pkg_prefix in path.parts(): + + if path.isdir() and path.join('__init__.py').check(file=1): + pkg_prefixes.add(path) + + for pkg_prefix in pkg_prefixes: + if pkg_prefix in path.parts() and pkg_prefix.join('__init__.py') == path: + skip = True + if skip: continue for x in self._collectfile(path): yield x - if isinstance(x, Package): - pkg_prefix = path.dirpath() def _get_xunit_setup_teardown(holder, attr_name, param_obj=None): diff --git a/testing/python/collect.py b/testing/python/collect.py index c040cc09e..7356597cb 100644 --- a/testing/python/collect.py +++ b/testing/python/collect.py @@ -1623,3 +1623,40 @@ def test_package_with_modules(testdir): root.chdir() result = testdir.runpytest("-v", "-s") result.assert_outcomes(passed=2) + + +def test_package_ordering(testdir): + """ + . + └── root + ├── TestRoot.py + ├── __init__.py + ├── sub1 + │ ├── TestSub1.py + │ └── __init__.py + └── sub2 + └── test + ├── TestSub2.py + └── test_in_sub2.py + + """ + testdir.makeini( + """ + [pytest] + python_files=Test*.py + """ + ) + root = testdir.mkpydir("root") + sub1 = root.mkdir("sub1") + sub1.ensure("__init__.py") + sub2 = root.mkdir("sub2") + sub2_test = sub2.mkdir("sub2") + + root.join("TestRoot.py").write("def test_1(): pass") + sub1.join("TestSub1.py").write("def test_2(): pass") + sub2_test.join("TestSub2.py").write("def test_3(): pass") + sub2_test.join("test_in_sub2.py").write("def test_4(): pass") + + # Execute from . + result = testdir.runpytest("-v", "-s") + result.assert_outcomes(passed=3)