pytest

时间:2018-04-02 05:33:28

标签: python unit-testing module pytest

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

src      
  __init__.py
  script1.py
  script2.py
test
  test_fun.py

但是,当我尝试通过命令行在pytest文件夹中运行test时,我看到以下错误

  

来自script2 import fun2
  E ModuleNotFoundError:没有名为'script2'的模块

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

script2.py

def fun2():
return('result_from_2')

script1.py

from script2 import fun2

def fun1():
    return(fun2()+'_plus_something')

test_fun.py

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?

3 个答案:

答案 0 :(得分:2)

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

修改 test_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'

答案 1 :(得分:1)

当我们运行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将能够解析您的类的导入。

答案 2 :(得分:0)

执行此操作的一种好方法是遵循Pytest docs中的建议,并结合此答案here中给出的第三种方法。 这意味着:

  1. 为您的项目创建一个简单的config.py。确保正确配置packagespackage_dir。阅读更多here
  2. 使用pip install -e .安装“可编辑”文件,这将在您的项目文件夹中创建.egg.info并安装它。
  3. 使用pytest对其进行测试。
  4. 使用pip uninstall name_of_package删除“可编辑”包,然后使用rm -r $(find . -name '*.egg-info')删除鸡蛋

我知道,这似乎比简单地更改sys.path的简单技巧要复杂,但这是一种更干净的方法。一开始让我很难理解的一件事是,使用此方法可以有效地安装软件包以进行测试。我没有用其他语言做到这一点。原因:

您可以将其视为也可以测试安装程序本身的一种方式。没有此步骤,就完全有可能通过测试套件,但安装程序已损坏(您最终会意外发布损坏的软件包)

(来自对此答案here的讨论)