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



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

该项目的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中被搜索了两次,但尽管PYTHONPATH在上面的命令行中被设置为包含./src/test/python路径,但./src/test/python没有被搜索。


示例测试代码

测试文件.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

Pylance

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中的东西下有不同的文件/目录名称,或者只使用一个指向src的名称