How do I Pytest a project using PEP 420 namespace packages?

别等时光非礼了梦想. 提交于 2019-11-30 21:10:50

The issue you are facing is that you place tests aside the production code inside namespace packages. As stated here, pytest recognizes your setup as standalone test modules:

Standalone test modules / conftest.py files

...

pytest will find foo/bar/tests/test_foo.py and realize it is NOT part of a package given that there’s no __init__.py file in the same folder. It will then add root/foo/bar/tests to sys.path in order to import test_foo.py as the module test_foo. The same is done with the conftest.py file by adding root/foo to sys.path to import it as conftest.

So the proper way to solve (at least part of) this would be to adjust the sys.path and separate tests from production code, e.g. moving test module thing_test.py into a separate directory project/util/tests. Since you can't do that, you have no choice but to mess with pytest's internals (as you won't be able to override the module import behaviour via hooks). Here's a proposal: create a repo/conftest.py with the patched LocalPath class:

# repo/conftest.py

import pathlib
import py._path.local


# the original pypkgpath method can't deal with namespace packages,
# considering only dirs with __init__.py as packages
pypkgpath_orig = py._path.local.LocalPath.pypkgpath

# we consider all dirs in repo/ to be namespace packages
rootdir = pathlib.Path(__file__).parent.resolve()
namespace_pkg_dirs = [str(d) for d in rootdir.iterdir() if d.is_dir()]

# patched method
def pypkgpath(self):
    # call original lookup
    pkgpath = pypkgpath_orig(self)
    if pkgpath is not None:
        return pkgpath
    # original lookup failed, check if we are subdir of a namespace package
    # if yes, return the namespace package we belong to
    for parent in self.parts(reverse=True):
        if str(parent) in namespace_pkg_dirs:
            return parent
    return None

# apply patch
py._path.local.LocalPath.pypkgpath = pypkgpath
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!