Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python pytest的ModuleNotFoundError问题_Python_Unit Testing_Module_Pytest - Fatal编程技术网

Python pytest的ModuleNotFoundError问题

Python pytest的ModuleNotFoundError问题,python,unit-testing,module,pytest,Python,Unit Testing,Module,Pytest,我想使用pytest对另一个名为src的文件夹中的脚本进行单元测试。以下是我的目录结构: src __init__.py script1.py script2.py test test_fun.py 但是,当我试图通过命令行在test文件夹中运行pytest时,我看到了以下错误 从script2导入fun2 E ModuleNotFoundError:没有名为“script2”的模块 在每个脚本中,我都有以下内容 script2.py: def fun2(): re

我想使用pytest对另一个名为
src
的文件夹中的脚本进行单元测试。以下是我的目录结构:

src      
  __init__.py
  script1.py
  script2.py
test
  test_fun.py
但是,当我试图通过命令行在
test
文件夹中运行
pytest
时,我看到了以下错误

从script2导入fun2
E ModuleNotFoundError:没有名为“script2”的模块

在每个脚本中,我都有以下内容

script2.py

def fun2():
return('result_from_2')
from script2 import fun2

def fun1():
    return(fun2()+'_plus_something')
import sys
sys.path.append('../')
from src.script1 import fun1

def test_fun1():        
    output1 = fun1()

    # check output
    assert output1=='result_from_2_plus_something'
script1.py

def fun2():
return('result_from_2')
from script2 import fun2

def fun1():
    return(fun2()+'_plus_something')
import sys
sys.path.append('../')
from src.script1 import fun1

def test_fun1():        
    output1 = fun1()

    # check output
    assert output1=='result_from_2_plus_something'
测试\u fun.py

def fun2():
return('result_from_2')
from script2 import fun2

def fun1():
    return(fun2()+'_plus_something')
import sys
sys.path.append('../')
from src.script1 import fun1

def test_fun1():        
    output1 = fun1()

    # check output
    assert output1=='result_from_2_plus_something'

如何使用上面提供的目录运行pytest?

导入文件时,Python只搜索当前目录、入口点脚本运行的目录和sys.path

修改test\u fun.py如下:

import sys
sys.path.insert(0, '../src/')
from script1 import fun1

def test_fun1():        
    output1 = fun1()

    # check output
    assert output1=='result_from_2_plus_something'

当我们运行pytest时,python使用sys.path查找模块以解析导入。那么,如果你的 测试位于路径“/Users/YourName/projectName/test”中,您需要从“/Users/YourName/projectName/src”导入一些模块 Python将无法找到它们

那么为什么Python可以找到“pytest”或“sys”?因为它们位于sys.path中存在的其他路径中

要验证现有路径,请使用:

  import pprint
  import sys
  pprint.pprint(sys.path)
您将看到python用于解析导入的可能路径列表:

  ['/Users/yourName/YourProject/test',
 '/opt/anaconda3/bin',
 '/opt/anaconda3/lib/python37.zip',
 '/opt/anaconda3/lib/python3.7',
 '/opt/anaconda3/lib/python3.7/lib-dynload',
 '/opt/anaconda3/lib/python3.7/site-packages',
 '/opt/anaconda3/lib/python3.7/site-packages/aeosa']
请注意,该列表不包含“/Users/YourName/projectName/src”。这就是为什么您需要在test_fun.py文件中使用以下命令在该列表中添加'src'路径

 import sys
 sys.path.append('/Users/YourName/projectName/src').
 from src.script1 import fun1
执行此命令后,列表如下所示:

 ['/Users/yourName/YourProject/test',
 '/opt/anaconda3/bin',
 '/opt/anaconda3/lib/python37.zip',
 '/opt/anaconda3/lib/python3.7',
 '/opt/anaconda3/lib/python3.7/lib-dynload',
 '/opt/anaconda3/lib/python3.7/site-packages',
 '/opt/anaconda3/lib/python3.7/site-packages/aeosa',
 '/Users/yourName/YourProject/src']

然后Python将能够解决类的导入问题。

一个好方法是遵循中的建议,并结合本答案中给出的第三种方法。 这意味着:

  • 为项目创建一个简单的config.py。确保正确配置
    软件包
    软件包目录
    。阅读更多
  • 使用
    pip Install-e安装一个“可编辑”的文件。这将在您的项目文件夹中创建.egg.info并安装它
  • 使用
    pytest
    对其进行测试
  • 使用
    pip uninstall name\u of_package
    删除该“可编辑”包,然后使用
    rm-r$(find.-name'*.egg info')删除egg
  • 我知道这似乎比简单的改变sys.path的黑客更复杂,但这是一种更干净的方法。一开始我很难理解的一件事是,使用这种方法可以有效地安装包进行测试。我在其他语言中没有这样做。原因是:

    您可以将其视为一种测试安装程序本身的方法。如果没有这个步骤,完全有可能有一个通过测试的套件,但安装程序却坏了(最终你会意外地发布一个坏包)


    (从这个答案的讨论中)

    这就是它在pytest中的工作原理: