Pytest:如何解决测试文件夹中缺少 __init__.py 的问题? [英] Pytest: how to work around missing __init__.py in the tests folder?

查看:285
本文介绍了Pytest:如何解决测试文件夹中缺少 __init__.py 的问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将所有 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.

更新:阅读这个答案后,我想我终于开始进一步了解 Python 导入的工作原理.

Update: After reading this answer I think I am finally starting to understand a bit more how python imports work.

推荐答案

添加 __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 ...)取决于 PYTHONPATHsys.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 的问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆