问题描述
我将所有 pytest 文件存储在项目根目录下的 tests
子目录中.该目录或以上目录中没有 __init__.py
并且 pytest tests/test_a.py
按预期工作.我还可以直接从 tests
文件夹中运行 pytest test_a.py
.
I am storing all the pytest files in the tests
sub-directory under the project root. There is no __init__.py
in that directory or above and pytest tests/test_a.py
works as expected. I can also run pytest test_a.py
directly from within the tests
folder.
|--<project_root>
+---[tests]
test_a.py
base.py
config.py
conftest.py
test_a.py
中的测试类继承自 base.py
.现在的问题是,由于缺少 __init__.py
,IDE 工具无法工作并且无法解析导入.在 tests
下添加 __init__.py
可以解决 IDE 中的所有导入错误,但是使用 pytest test_a.py
将不再运行测试,因为 py.test 无法导入 conftest.py
.
The test class in test_a.py
inherits from base.py
. Now, the problem is that because of the missing __init__.py
the IDE tooling does not work and the imports cannot be resolved. Adding __init__.py
under the tests
resolves all import errors in the IDE, but tests won't run anymore with pytest test_a.py
because py.test fails to import conftest.py
.
在我的 conftest.py
中,我有以下导入:
In my conftest.py
I have the following imports:
from config import HOST_URL_DEFAULT, USER, PASSWORD
导致:
ModuleNotFoundError: No module named 'config'
ERROR: could not load /project_root/tests/conftest.py
有没有办法解决这个问题,以便 IDE 工具 和 pytest
继续工作?如果可能,我想避免使用点导入.
Is there a way to solve this so that both IDE tooling works and pytest
keeps working? I would like to avoid using dot imports, if possible.
推荐答案
添加 __init__.py
并在 conftest.py
中使用相对或绝对导入:
Add __init__.py
and use a relative or absolute import in conftest.py
:
# relative
from .config import HOST_URL_DEFAULT, USER, PASSWORD
# absolute
from tests.config import HOST_URL_DEFAULT, USER, PASSWORD
在包中(由 __init__.py
标识),您需要明确的导入路径.使用不合格的导入(from config import ...
)取决于 PYTHONPATH
或 sys.modules
包括您的包根 - 这通常不健壮,并且应该避免,因为它绕过了包基础结构.
In a package (identified by __init__.py
), you need unambiguous import paths. Using unqualified imports (from config import ...
) depends on PYTHONPATH
or sys.modules
including your package root - this is generally not robust and should be avoided as it circumvents the package infrastructure.
您在这里拥有的(config.py
被其他模块使用) 是一个包.把它当作一个.
What you have here (config.py
used by other modules) is a package. Treat it as one.
pytest
不不鼓励使用带有 __init__.py
的测试包!这有真正的用例 - 比如你的.
pytest
does not discourage the use of a test package with an __init__.py
! There are veritable use cases for this - such as yours.
pytest
做什么劝阻是在同一个源根目录下有一个源包和测试包.但是,这意味着您应该移动源包,而不是测试包!
What pytest
does discourage is having a source package and test package in the same source root. However, that means you should move your source package, not your test package!
mysource/ # root directory for both mypackage and mytests
+- mypackage/ # should be src/mypackage instead!
+- __init__.py
+- abcd.py
+- mytests
+- __init__.py
+- tests_abcd.py # ``from mypackage import abcd`` imports from source
问题是运行 mytests
意味着 mypackage
也可以从源代码导入.也就是说,您的测试针对的是源代码包,而不是已安装的包.如果您的安装过程中有任何错误,测试将无法捕捉到它.查看pytest
中链接的博客有关详细信息的文档.
The problem is that running mytests
means that mypackage
is importable from source as well. That is, your tests are working on your source package, not your installed package. If there are any errors in your installation procedure, testing will not catch it. See the blog linked in the pytest
docs for details.
这篇关于Pytest:如何解决测试文件夹中缺少 __init__.py 的问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!