问题描述
Terminal中通过pytest执行用例会返回异常:ModuleNotFoundError: No module named '***'
通过python -m pytest执行用例可以正常执行
通过pycharm进行执行对应的用例文件,可以正常执行
目录结构及test_login.py的文件内容如下:

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

上图中第一项是'',使用OS模块查看
.png)
发现第一项是当前文件的目录,所以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/tests 到 sys.path  ,同样,conftest.py也被视为独立的模块,通过添加其所在目录root/foo到sys.path中,将其以模块形式导入。
 
    
默认评论
Halo系统提供的评论