首页 > 解决方案 > Pytest 奇怪的 ImportError

问题描述

在我的项目上运行 PyTest 时遇到了一个奇怪的问题。项目结构看起来像这样。

myproject
├── env
│   └── stuff
├── __init__.py
├── myproject
│   ├── __init__.py
│   └── myfile.py
└── tests
    ├── __init__.py
    └── framework
        └── unit
            └── test_myfile.py

myproject/myproject 中的代码运行良好。此外,myproject 根目录中的代码文件夹将 myproject/myproject 中的代码作为模块引用。

但是当我使用以下语法运行pytest时(在virutalenv中)

(env) myproject $ python3.6 -m pytest tests/framework

所有测试都失败并显示以下错误消息:

E           ModuleNotFoundError: No module named 'myproject.tests'


E               _pytest.nodes.Collector.CollectError: ImportError while importing test module '/home/myuser/projects/myproject/tests/__init__.py'.
E               Hint: make sure your test modules/packages have valid Python names.
E               Traceback:
E               ModuleNotFoundError: No module named 'myproject.tests'

的输出

(env) myproject $ python3.6 -c "import sys; print('\n'.join(sys.path))" 

/home/myuser/projects/myproject/env/lib/python36.zip
/home/myuser/projects/myproject/env/lib/python3.6
/home/myuser/projects/myproject/env/lib/python3.6/lib-dynload
/usr/lib/python3.6
/home/myuser/projects/myproject/env/lib/python3.6/site-packages

通过其他帖子中的答案,即使我通过 .pth 文件手动将 myproject、myproject/myproject 和 myproject/tests 添加到路径中,我也会收到相同的错误消息。

修复错误消息的方法是在 myproject/myproject 中添加一个名为测试的空文件夹。完成后,错误消息消失并且测试运行良好。谁能解释导致这种奇怪行为的原因?

编辑:评论中的解决方案。问题是由于不应该存在的顶级init .py 造成的。

标签: pythonvirtualenvpytest

解决方案


我有一些动态导入的类似问题,我发现这可以解决我的问题

如果您在此文件ekiim/panflute/utils.py(Github 代码)ContextImport的第 46 行检查类

该类的作用是它用作上下文管理器,因此您可以给它一个文件(及其绝对路径),然后它将文件导入该上下文。

因此,也许通过修改此上下文管理器,您可以将项目目录放入路径中,然后还原更改(退出上下文时)。

该类通过将路径放在sys.path列表的第一个条目中来工作,也许那是您的问题,而您只是附加到路径列表中。

不过,我不确定这是否可以被认为是正确的或 pythonic。


推荐阅读