Python模拟函数

unittest.mock 或Mock 函数是一个用于Python测试的库,它允许你用mock 对象替换被测系统的部件,并对这些部件的使用情况作出断言。

unittest.mock 给出了一个核心的Mock 类,消除了在你的测试套件中创建大量存根的必要性。

在执行一个过程后,你可以断言哪些方法或属性被使用,以及它们被调用的参数。你还可以指定返回值,并以通常的方式设置所需的属性。

此外,Mock 提供了一个patch() 装饰器,可以处理测试范围内的修补模块和类级属性,还有一个帮助器sentinel ,用于创建独特的对象。

Mock 洛克菲勒是为了与 一起使用而创建的,它基于 模式,而不是 ,后者被用于大多数嘲讽框架中。 有一个用于Python先前版本的回传。unittest action-to-assertion record-to-replay unittest.mock

设置和安装Pytest Mock

与unittest 相比,pytest 不是一个内置的Python包,需要安装。这可以通过在终端输入以下命令来安装。

pip install pytest

作为说明,unittest 的最佳实践也适用于pytest ,例如:

  • 需要一个tests/ 目录来包含所有单元测试。
  • 文件名必须总是以tests_ 开头。
  • 函数名称必须总是以the test 开头。

命名标准必须被遵守,以便检查员可以找到所执行的单元测试。

在你使用pytest-mock 之前,需要安装它。下面是如何使用pip 来安装它:

pip install pytest-mock

这是一个Pytest的插件。因此,如果你还没有这样做,它将安装Pytest。

模拟一个函数

首先,创建一个简单的函数get_os() ,告诉我们是使用Windows还是Linux作为操作系统。

创建一个名为app.py 的文件,如下所示:

from time import sleep
def isWindows():
    # This sleep can be some complex operation
    sleep(5)
    return True
def get_os():
    return 'Windows is the current OS' if isWindows() else 'Linux is the current OS'

这个函数使用isWindows 函数来确定当前的操作系统是否是Windows。假设这个isWindows 函数相当复杂,需要几秒钟的时间来运行,这里我们可以模拟这个慢速运行的函数,每次调用它时,进入程序睡眠5秒钟。

下面将是一个get_os() 函数的pytest :

创建一个名为test_app.py 到pytest 的文件:

from app import get_os
def test_get_os():
    assert get_os() == 'Windows is the current OS'

由于get_os() 调用了一个较慢的函数isWindows ,所以测试进行的很慢。这可以从下面执行pytest 的输出中看出。

它花了5.02秒,而且会因当前实例的不同而不同。
在这里插入图片描述
单元测试需要快速,我们应该能够在几秒钟内执行数百个测试。测试套件被一个耗时5秒的测试拖累了,所以应用嘲讽让我们的生活更轻松。

如果我们给慢速运行的函数打上补丁,我们就可以验证get_os() 函数的行为,而不必停留5秒钟。

让我们用pytest-mock 来模拟这个函数。

Pytest-mock 在Python的集成嘲弄结构之上,提供了一个叫做 的固定装置和一个精细的接口。你可以通过从它那里调用mock和patch函数,并将它们作为参数发送到你的测试函数,来采用一个mocker。mocker

在一个案例中,你想让isWindows 函数返回True ,而不需要等待那宝贵的5秒钟,我们可以对它进行修补,如下所示:

mocker.patch('app.isWindows', return_value=True)

在这里,你必须把isWindows 称为app.isWindows ,因为它是app 模块中的函数。如果我们只修补isWindows ,它将试图修补test_app 文件中的一个名为isWindows 的函数,而这个函数并不存在。

格式总是<module_name>.<function_name> ,知道如何正确的模拟是至关重要的。

下面描述了打完补丁后修改后的测试函数:

from app import get_os
# Python小白学习交流群:153708845
# using'mocker' fixture provided by pytest-mock
def test_get_os(mocker):
    # mocking the slow-going function and returning True always
    mocker.patch('app.isWindows', return_value=True)
    assert get_os() == 'Windows is the current OS'

现在,当你运行这个测试时,它会更快地完成。
在这里插入图片描述
正如你所看到的,这个测试只花了0.02秒,所以我们成功地修补了慢速运行的函数,加速了测试套件的运行。

嘲讽的另一个好处是,你可以让嘲讽函数返回任何东西,甚至可以让它引发错误,以测试你的代码在这些情况下是如何处理的。

在这里,如果你想测试isWindows ,返回False 的情况,写出以下测试:

from app import get_os
def test_os_isLinux(mocker):
    mocker.patch('app.isWindows', return_value=False) # set the return value to be False
    assert get_os() == 'Linux is the current OS'

mocker附带的mock和patches都是函数范围的,这意味着它们只能用于那个特定的函数。因此,在不同的测试中,同一函数的补丁之间不会有任何冲突。

总结

嘲弄是用一个嘲弄来代替你正在测试的应用程序组件的做法,它是该组件的一个假实现。通过嘲弄,我们可以得到一些好处,如提高速度,测试运行速度快是非常有益的,在测试过程中避免不希望出现的副作用,等等。

posted @ 2023-09-20 16:17  小小程序员ol  阅读(83)  评论(0编辑  收藏  举报