tests: use updated conftest from pymplate, this allows to run individual test modules properly

e.g. pytest --pyargs my.core.tests.test_get_files
This commit is contained in:
Dima Gerasimov 2024-08-06 20:41:50 +01:00 committed by karlicoss
parent b615ba10b1
commit 3aebc573e8
2 changed files with 54 additions and 2 deletions

47
conftest.py Normal file
View file

@ -0,0 +1,47 @@
# this is a hack to monkey patch pytest so it handles tests inside namespace packages without __init__.py properly
# without it, pytest can't discover the package root for some reason
# also see https://github.com/karlicoss/pytest_namespace_pkgs for more
import os
import pathlib
from typing import Optional
import _pytest.main
import _pytest.pathlib
# we consider all dirs in repo/ to be namespace packages
root_dir = pathlib.Path(__file__).absolute().parent.resolve() # / 'src'
assert root_dir.exists(), root_dir
# TODO assert it contains package name?? maybe get it via setuptools..
namespace_pkg_dirs = [str(d) for d in root_dir.iterdir() if d.is_dir()]
# resolve_package_path is called from _pytest.pathlib.import_path
# takes a full abs path to the test file and needs to return the path to the 'root' package on the filesystem
resolve_pkg_path_orig = _pytest.pathlib.resolve_package_path
def resolve_package_path(path: pathlib.Path) -> Optional[pathlib.Path]:
result = path # search from the test file upwards
for parent in result.parents:
if str(parent) in namespace_pkg_dirs:
return parent
if os.name == 'nt':
# ??? for some reason on windows it is trying to call this against conftest? but not on linux/osx
if path.name == 'conftest.py':
return resolve_pkg_path_orig(path)
raise RuntimeError("Couldn't determine path for ", path)
_pytest.pathlib.resolve_package_path = resolve_package_path
# without patching, the orig function returns just a package name for some reason
# (I think it's used as a sort of fallback)
# so we need to point it at the absolute path properly
# not sure what are the consequences.. maybe it wouldn't be able to run against installed packages? not sure..
search_pypath_orig = _pytest.main.search_pypath
def search_pypath(module_name: str) -> str:
mpath = root_dir / module_name.replace('.', os.sep)
if not mpath.is_dir():
mpath = mpath.with_suffix('.py')
assert mpath.exists(), mpath # just in case
return str(mpath)
_pytest.main.search_pypath = search_pypath

View file

@ -175,12 +175,17 @@ TMP = tempfile.gettempdir()
test_path = Path(TMP) / 'hpi_test'
def setup():
@pytest.fixture(autouse=True)
def prepare():
teardown()
test_path.mkdir()
try:
yield
finally:
teardown()
def teardown():
def teardown() -> None:
if test_path.is_dir():
shutil.rmtree(test_path)