【发布时间】:2022-01-03 18:49:12
【问题描述】:
Therewerealready 有关此主题的问题。有时程序员会在某些地方放一些__init__.py,通常说应该使用绝对路径。但是,我不让它在这里工作:
如何从包中导入类,以便在 pytest 中运行测试并使用代码?
目前我得到 pytest 或通过各自运行的代码。
我的示例项目结构是
.
├── testingonly
│ ├── cli.py
│ ├── __init__.py
│ └── testingonly.py
└── tests
├── __init__.py
└── test_testingonly.py
__init__.py 在这两种情况下都是一个空文件。
$ cat testingonly/cli.py
"""Console script for testingonly."""
from testingonly import Tester
def main(args=None):
"""Console script for testingonly."""
te = Tester()
return 0
main()
$ cat testingonly/testingonly.py
"""Main module."""
class Tester():
def __init__(self):
print("Hello")
这给出了 - 正如预期的那样:
$ python3 testingonly/cli.py
Hello
但是,尝试对此进行测试失败:
$ pytest
========================================================= test session starts =========================================================
platform linux -- Python 3.7.3, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: /home/stefan/Development/testingonly
collected 0 items / 1 error
=============================================================== ERRORS ================================================================
_____________________________________________ ERROR collecting tests/test_testingonly.py ______________________________________________
ImportError while importing test module '/home/stefan/Development/testingonly/tests/test_testingonly.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/usr/lib/python3.7/importlib/__init__.py:127: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
tests/test_testingonly.py:10: in <module>
from testingonly import cli
testingonly/cli.py:2: in <module>
from testingonly import Tester
E ImportError: cannot import name 'Tester' from 'testingonly' (/home/stefan/Development/testingonly/testingonly/__init__.py)
将testingonly/testingonly.py 重命名为testingonly/mytest.py 并更改test_testingonly.py(来自testingonly import mytest)和cli.py(来自mytest import Tester)中的导入
$ pytest
========================================================= test session starts =========================================================
platform linux -- Python 3.7.3, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: /home/stefan/Development/testingonly
collected 0 items / 1 error
=============================================================== ERRORS ================================================================
_____________________________________________ ERROR collecting tests/test_testingonly.py ______________________________________________
ImportError while importing test module '/home/stefan/Development/testingonly/tests/test_testingonly.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/usr/lib/python3.7/importlib/__init__.py:127: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
tests/test_testingonly.py:10: in <module>
from testingonly import cli
testingonly/cli.py:2: in <module>
from mytest import Tester
E ModuleNotFoundError: No module named 'mytest'
======================================================= short test summary info =======================================================
ERROR tests/test_testingonly.py
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
========================================================== 1 error in 0.37s ===========================================================
$ python3 testingonly/cli.py
Hello
另一个建议的解决方案是重命名为 mytest.py 让测试通过,但在 cli.py 中使用 from testingonly.mytest import Tester 会产生 NameNotFound 错误。
$ python3 testingonly/cli.py
Traceback (most recent call last):
File "testingonly/cli.py", line 2, in <module>
from testingonly.mytest import Tester
ModuleNotFoundError: No module named 'testingonly'
$ pytest
========================================================= test session starts =========================================================
platform linux -- Python 3.7.3, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: /home/stefan/Development/testingonly
collected 1 item
tests/test_testingonly.py . [100%]
========================================================== 1 passed in 0.12s ==========================================================
【问题讨论】:
-
这个关于相关 Python Imports 的答案也可能会有所帮助stackoverflow.com/questions/2183205/…
-
首先
from testingonly import Tester是错误的。Tester类在模块中定义为 qualnametestingonly.testingonly,因为它没有在testingonly/__init__.py中导出,因此导入将无法解析。它在testingonly.cli中有效,只是因为它与testingonly.testingonly处于同一级别,并且具有相对导入作为后备。要验证,请在根目录中创建一些foo.py并使用一行from testingonly import Tester并运行python foo.py- 您将得到相同的错误。 -
其次,
pytest默认情况下不会将项目根目录添加到sys.path- 您应该自己处理。运行python -m pytest,或者将一个名为conftest.py的空文件添加到项目根目录。查看PATH issue with pytest 'ImportError: No module named YadaYadaYada' 中的答案了解更多详情。 -
啊,
from testingonly import Tester的正确替换当然是from testingonly.testingonly import Tester
标签: python pytest python-import