Pytest:如何解决测试文件夹中缺少 __init__.py 的问题?
Pytest: how to work around missing __init__.py in the tests folder?
我将所有pytest文件存储在项目根目录下的tests
子目录中。该目录或更高目录中没有 __init__.py
,pytest 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 ...
) 取决于 PYTHONPATH
或 sys.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.
我将所有pytest文件存储在项目根目录下的tests
子目录中。该目录或更高目录中没有 __init__.py
,pytest 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 ...
) 取决于 PYTHONPATH
或 sys.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.