Pytest:如何解决测试文件夹中缺少 __init__.py 的问题?

Pytest: how to work around missing __init__.py in the tests folder?

我将所有pytest文件存储在项目根目录下的tests子目录中。该目录或更高目录中没有 __init__.pypytest tests/test_a.py 按预期工作。我也可以直接从 tests 文件夹中 运行 pytest test_a.py

|--<project_root>
+---[tests]
    test_a.py
    base.py
    config.py
    conftest.py

test_a.py中的测试class继承自base.py。现在,问题是由于缺少 __init__.py,IDE 工具无法正常工作,无法解决导入问题。在 tests 下添加 __init__.py 可解决 IDE 中的所有导入错误,但使用 pytest test_a.py 时不会再 运行 因为 py.test 无法导入 conftest.py.

在我的 conftest.py 中,我有以下导入:

from config import HOST_URL_DEFAULT, USER, PASSWORD

这导致:

ModuleNotFoundError: No module named 'config'
ERROR: could not load /project_root/tests/conftest.py

有没有办法解决这个问题,让 IDE 工具 pytest 都能正常工作?如果可能的话,我想避免使用点导入。

更新: 阅读 this answer 之后,我想我终于开始更多地了解 python 导入是如何工作的。

添加 __init__.py 并在 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 ...) 取决于 PYTHONPATHsys.modules,包括您的包根 - 这通常不可靠,应该避免,因为它绕过了包基础结构。

你这里的(config.py被其他模块使用)一个包。把它当作一个。


pytest 不会 不鼓励使用带有 __init__.py 的测试包!这有很多真实的用例 - 比如你的。

什么 pytest does discourage 在同一个源根目录中有一个源包 测试包。但是,这意味着您应该移动您的源包,而不是您的测试包!

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 也可以从源代码导入。也就是说,您的测试是在您的 源包 上进行的,而不是您安装的包。如果您的安装过程中有任何错误,测试将不会发现它。 See the blog linked in the pytest docs for details.