首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

pytest的内置插件盘点15. monkeypatch

本文系《pytest源码剖析》系列内容

15. monkeypatch

插件路径:_pytest.monkeypatch

实现的 hook

调用的 hook

定义的 fixture

monkeypatch

作用域:functions

返回值:MonkeyPatch实例对象

插件功能

创建猴子补丁类:MonkeyPatch,可以修改

对象属性

字典 item

当前目录

环境变量

syspath

创建 fixture:monkeypatch

用例结束后,自动还原修改

创建函数:resolve

从a.b.c格式的字符串加载对象

代码片段

@fixturedef monkeypatch() -> Generator["MonkeyPatch", None, None]: mpatch = MonkeyPatch() yield mpatch mpatch.undo()

class MonkeyPatch: @classmethod @contextmanager def context(cls) -> Generator["MonkeyPatch", None, None]: m = cls() try: yield m finally: m.undo()

fixturemonkeypatch基本说明了MonkeyPatch的用法

MonkeyPatch也支持上下文管理器方式直接使用

MonkeyPatch 用法示例

1. 简单的示例

import requestsfrom requests.sessions import Session

def test_mock(monkeypatch): # 使用fixture,有mock效果 def mock_request(*args, **kwargs): raise ValueError('禁止使用requests发送网络请求') monkeypatch.setattr(Session, 'request', mock_request) # 进行mock

requests.get('https://www.baidu.com')

def test_mock_undo(): # 在另一个用例中,不受mock影响 resp = requests.get('https://www.baidu.com') assert resp.status_code == 200

2. 常用的场景

class MockResponse: status_code = 444 text = 'sanmu'

def test_mock(monkeypatch): def mock_request(*args, **kwargs): return MockResponse() # 返回MockResponse,而不是发送真实的网络请求

monkeypatch.setattr(Session, 'request', mock_request)

resp = requests.get('https://www.baidu.com') assert resp.status_code == 444 assert resp.text == 'sanmu'

3. 其他用法

除了修改属性之外,还可以删除属性,使得对象在被使用时引发异常

不仅是对象的属性,以下类型都可以进行进行修改 / 删除:

字典

环境变量

syspath

cwd

其实展开来讲值得专门写一篇,欢迎关注后续更新

简评

此前看到一些在测试中需要 mock 的代码,使用了unittest中的mock,类似这样:

虽然【在一个测试框架中使用另一个框架的功能】有一种奇怪的违和感,

但是想到unittest是 python 标准库,这似乎又很合理

在这次源码剖析的过程中,居然终于通过源码找到了 pytest 自带的 mock 功能,

可以说意外之喜了,刚好可以消灭这奇怪又合理的违和感 :)

...

monkeypatch和mock有什么区别?

简单来说,mock 是目的,monkeypatch 是手段

pytest 和 unittest 在实现 mock 的方式上,其实都是属于 monkeypatch`

测试替身 (Test double) 是自动化测试中的术语,为了简化系统、降低复杂性,促成快速、稳定的测试活动。

常见的类型有:

mock:预设结果,并不真的做出访问动作

stub:预设结果,也做出访问动作

fake:做出访问动作,访问低成本替代品,而不是真实的高成本资源

mock 是相对简单、方便、灵活的一种方式,

比如在测试用例中需要调用某接口、某数据库,但是苦于此时网络无法连接,

那么通过对调用接口的代码(或调用数据库的代码)进行 mock,让其直接返回结果,

就可以继续进行下面步骤了。

注意:mock 让我们并没有真正连接网络,却得到结果,成本是最低的

在动态语言中,monkeypatch是非常方便的 mock 方式,其工作原理是:

在代码运行时,直接修改被 mock 对象,导致被 mock 对象的执行方式被改变

  • 发表于:
  • 原文链接https://page.om.qq.com/page/OQZSKrkhwgvqfKyOMZF7YXvQ0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券