浮生闲记
2025-04-23
点 赞
0
热 度
7
评 论
0

pytest导入自定义模块报错

文章摘要

摘要

pytest导入自定义模块报错

问题描述

Terminal中通过pytest执行用例会返回异常:ModuleNotFoundError: No module named '***'

通过python -m pytest执行用例可以正常执行

通过pycharm进行执行对应的用例文件,可以正常执行

目录结构及test_login.py的文件内容如下:

问题原因

默认情况下,Python解释器会搜索当前目录、所有已安装的内置模块和第三方模块,搜索路径存放在sys模块的path变量中,如果找不到模块所在的路径就会报错,所以自定义模块要处于 sys.path 里才能被导入。

上图中第一项是'',使用OS模块查看

发现第一项是当前文件的目录,所以V3.utils 即不在test_login.py当前目录下,也不在所有已安装的内置模块和第三方模块,肯定找不到,那为什么通过python -m pytest执行和通过pycharm进行执行,可以正常执行呢?

python -m pytest会把当前项目的目录添加到sys.path(指定模块的搜索路径)中,通过pycharm进行运行的时候也会把项目当前所在路径添加到sys.path中

问题解决

网上大部分的解决办法都是手动添加到sys.path中

方法一

直接修改sys.path,添加要搜索的目录:

>>> import sys
>>> sys.path.append('文件路径')

这种方法是在运行时修改,运行结束后失效。

方法二

test_login.py中将目录直接加进去就行

path = os.path.abspath(os.path.dirname(os.path.dirname(__f11e__)))
sys.path.insert(0,path)

方法三

由于手动添加总觉得有些麻烦,不想手动添加也可以进行导入,所以只需要在根目录下新建一个conftest.py文件或者scripts下新建一个__init__.py文件即可

为了解答此疑惑,了解了一下pytest导入模块的机制,以以下目录进行说明

例如:

root/
|- foo/
   |- __init__.py
   |- conftest.py
   |- bar/
      |- __init__.py
      |- tests/
         |- __init__.py
         |- test_foo.py

执行pytest root/后,Pytest首先会找到 foo/bar/tests/test_foo.py ,因为同一文件夹中存在__init__.py ,所以foo/bar/tests/会被识别成package,然后它会向上搜索,直到找到仍包含 __init__.py 的最后一个文件夹 ,此处是foo/,所以他会将root/ 到插入到 sys.path ,这样就可以使test_foo.py 作为模块 foo.bar.tests.test_foo 导入

相同的逻辑也适用于该conftest.py文件:它将作为foo.conftest模块导入。

root/
|- foo/
   |- conftest.py
   |- bar/
      |- tests/
         |- test_foo.py

执行pytest root/后,Pytest首先会找到 foo/bar/tests/test_foo.py ,因为同一文件夹中不存在__init__.py,所以不会被识别成package,会把用例视为一个独立的模块。然后为了导入 test_foo.py 它会添加 root/foo/bar/testssys.path ,同样,conftest.py也被视为独立的模块,通过添加其所在目录root/foosys.path中,将其以模块形式导入。


用键盘敲击出的不只是字符,更是一段段生活的剪影、一个个心底的梦想。希望我的文字能像一束光,在您阅读的瞬间,照亮某个角落,带来一丝温暖与共鸣。

浮生闲记

intj 建筑师

站长

具有版权性

请您在转载、复制时注明本文 作者、链接及内容来源信息。 若涉及转载第三方内容,还需一同注明。

具有时效性

目录

欢迎来到浮生闲记的站点,为您导航全站动态

26 文章数
3 分类数
1 评论数
5标签数
最近评论
二十七度风

二十七度风


已Mark

访问统计