pytest/python 无法从 python 测试中导入测试助手代码

pytest/python fails to import test helper code from within python test

我在将测试助手导入测试代码时遇到问题。

该项目的python源代码目录和测试代码目录是分开的,但它们的结构是相似的。在测试目录中,我有一些我想导入到实际测试中的辅助测试代码。我将 PYTHONPATH 设置为包括主 src 目录和测试目录(详情如下)。

命令行:

PYTHONPATH="$(pwd)/src/main/python:$(pwd)/src/test/python" poetry run python -m pytest --import-mode=importlib ${@} ./src/test/python

预期:

从测试中导入测试助手模块会起作用。

实际:

_ ERROR collecting src/test/python/module_A/module_1/test_file.py _
ImportError while importing test module '/Users/<username>/git/src/test/python/module_A/module_1/test_file.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
src/test/python/module_A/module_1/test_file.py: in <module>
    from module_A.module_1.test_helpers.helper_a import HelperA
E   ModuleNotFoundError: No module named 'module_A.module_1.test_helpers'

注意:如果我将测试目录结构更改为不再与 src 目录结构平行,问题就会消失。

如有任何帮助,我们将不胜感激。如果需要,我很乐意提供更多信息。

调试输出:

我已经将 -v -v -v -v 传递给上面的 python (python -v -v -v -v -m pytest . . .),我看到了以下内容:

...
# trying /Users/<username>/git/proj/src/main/python/module_A/test_helpers.cpython-38-darwin.so
# trying /Users/<username>/git/proj/src/main/python/module_A/test_helpers.abi3.so
# trying /Users/<username>/git/proj/src/main/python/module_A/test_helpers.so
# trying /Users/<username>/git/proj/src/main/python/module_A/test_helpers.py
# trying /Users/<username>/git/proj/src/main/python/module_A/test_helpers.pyc
# trying /Users/<username>/git/proj/src/main/python/module_A/test_helpers.cpython-38-darwin.so
# trying /Users/<username>/git/proj/src/main/python/module_A/test_helpers.abi3.so
# trying /Users/<username>/git/proj/src/main/python/module_A/test_helpers.so
# trying /Users/<username>/git/proj/src/main/python/module_A/test_helpers.py
# trying /Users/<username>/git/proj/src/main/python/module_A/test_helpers.pyc
...

似乎认为 test_helpers 在 ./src/main/python 中搜索了两次,但是 ./src/test/python 没有被搜索,尽管 PYTHONPATH 设置为包含 ./src/test/python 上面命令行中的路径。


示例测试代码:

test_file.py

from pytest import mark

# This is where we have an error in the code editor despite
# this running fine.
#
# Import module_A.mocule_1.file could not be resolved
from module_A.test_helpers.helper_a import HelperA

@mark.unit_test
class Handler_tests:
    def test_happy_path(self):
        with HelperA():
            pass

helper_a.py(位于./src/test/python/module_A/test_helpers/

class HelperA:
    def __init__(self):
        # No impl here
        pass

项目目录结构:

// note, some non-python code directories/files exist but are omitted
<proj_root>
├──README.md
├──.env
└──src
    ├── main
    │   └── python
    │       └── module_A
    │           ├── __init__.py
    │           └── module_1
    │               ├── __init__.py
    │               └── file.py
    └── test
        └── python
            ├── conftest.py
            └── module_A
                ├── __init__.py
                └── test_helpers
                    ├── __init__.py
                    └── helper_a
                └── module_1 
                     └── test_file.py  

环境信息: Python

python ~3.8
pytest 6.0.0

VS 代码

Version: 1.63.0-insider (Universal)
Commit: bedf867b5b02c1c800fbaf4d6ce09cefbafa1592
Date: 2021-11-18T05:17:00.890Z (3 wks ago)
Electron: 13.5.2
Chromium: 91.0.4472.164
Node.js: 14.16.0
V8: 9.1.269.39-electron.0
OS: Darwin arm64 21.1.0

皮兰斯

v2021.12.2-pre.1

好的,你的笔记让我了解了可能发生的事情。

如果你这样使用导入:

from module_A.test_helpers.helper_a import HelperA

这表明您的 PYTHONPATH(因此 sys.path)同时包含 src/main/pythonsrc/test/python

为了导入模块,python 按顺序查找 sys.path 中的所有路径并搜索特定模块。不幸的是,它不够聪明,无法检查完整路径 - 它找到的第一个地方 module_A 它假定它是那个并尝试解析其余路径。您的 src/main/python 路径是第一个,并且由于显而易见的原因,它无法在那里找到 test_helpers。它不会从 sys.path 搜索其他路径,并且不确定是否有办法强制执行它。我知道的唯一解决方案是在 PYTHONPATH 中的东西下使用不同的 files/directories 名称,或者只使用一个指向你的 src