【发布时间】:2021-01-26 22:31:57
【问题描述】:
我正在一个名为test (https://github.com/covid-projections/covid-data-model/tree/main/test) 的目录中包含测试和一些测试帮助程序库的存储库中工作。神秘地pip install dash 似乎打破了我们的测试。我在 debian 笔记本电脑上的 pyenv 中使用 python 3.7.9。我用一个非常简单的例子重现了这个问题:
激活新的 pyenv virtualenv 并使用 pip install git+https://github.com/pytest-dev/pytest 安装最新的 pytest。创建一个空的./test/__init__.py 和以下两个文件:
$ cat ./test/real_test.py
from test import test_helpers
def test_one():
assert "foobar" == test_helpers.SOME_CONSTANT
$ cat ./test/test_helpers.py
SOME_CONSTANT = "foo"
运行 test/real_test.py 符合预期,但未通过测试。现在pip install dash==1.19.0 测试无法运行
_____________________________________________________________________________ ERROR collecting test/real_test.py _____________________________________________________________________________
ImportError while importing test module '/home/thecap/tmp/nomodule/test/real_test.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
../../.pyenv/versions/3.7.9/lib/python3.7/importlib/__init__.py:127: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
E ModuleNotFoundError: No module named 'test.real_test'
运行pytest --import-mode=importlib test/real_test.py(在https://github.com/pytest-dev/pytest/issues/7408 的cmets 中找到)给了我一点提示,它不包括用于搜索库的路径中的cwd,因为它正在查看pyenv 中的test ,而不是在 cwd 中。
ImportError while importing test module '/home/thecap/tmp/nomodule/test/real_test.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
test/real_test.py:1: in <module>
from test import test_helpers
E ImportError: cannot import name 'test_helpers' from 'test' (/home/thecap/.pyenv/versions/3.7.9/lib/python3.7/test/__init__.py)
在运行 pip uninstall dash 后对我来说神秘的是,pytest test/real_test.py 的测试按预期运行,但 pytest --import-mode=importlib test/real_test.py 仍然无法正常运行。
我怀疑将我们的测试从 test/ 移动到 tests/ 可以解决这个问题,但我想了解为什么安装 dash 会破坏事情,如果我们当前的设置有问题,请帮助其他人避免它。
(我也在https://github.com/pytest-dev/pytest/discussions/8270 发布了这个帖子,希望对堆栈溢出有更多的回应。)
【问题讨论】:
-
这是一个有趣的问题,当安装了
dash时,不知何故rootdir 不在sys.path中。在没有插件活动的情况下运行工作:pytest test/real_test.py -p no:dash,还显式地将根目录添加到sys.path工作:python -m pytest test/real_test.py或PYTHONPATH=. pytest test/real_test.py。不过,我仍然不明白为什么安装dash会破坏它。 -
我猜
dash的问题是它使用来自futures的代码,在安装别名时导入test,因此当pytest开始测试时,您的本地包以后无法导入collection (pytest将项目根目录添加到sys.path并调用import test,但sys.modules已经包含来自stdlib 的test,所以它没有效果。这就是为什么提前将根目录添加到sys.path够用了,但是我想别名futures会出错)。 -
简短回答 - 不要创建名称隐藏标准库的包或模块,这迟早会破坏某些东西:-)
-
虽然我也想说这根本不是你的错 -
testmodule docs 明确指出它仅供 Python 内部使用。 我宁愿令标准库在内部回归测试运行之外使用它感到惊讶。作为一种解决方法,我可以建议在项目根目录中创建一个conftest.py,内容为import sys; sys.modules.pop("test", None)- 这应该可以解决导入问题。 -
非常感谢@hoefling!我测试了 conftest.py 解决方法,我们将把 test 重命名为 tests。我还将更新 github 讨论并尝试使用 stdlib 提交错误。