pytest之Monkeypatching(猴子补丁)

2023-12-13 03:48

本文主要是介绍pytest之Monkeypatching(猴子补丁),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

猴子补丁(monkey patching)理解

在运行时动态修改模块、类或函数,通常是添加功能或修正缺陷。
猴子补丁在代码运行时(内存中)发挥作用,不会修改源码,因此只对当前运行的程序实例有效。
因为猴子补丁破坏了封装,而且容易导致程序与补丁代码的实现细节紧密耦合,所以被视为临时的变通方案,不是集成代码的推荐方式。
在Python语言中,monkey patch 指的是对于一个类或者模块所进行的动态修改。在Python语言中,我们其实可以在运行时修改代码的行为。

monkeypatch使用场景

该monkeypatch固定装置提供了这些帮助程序方法,用于安全地修补和模拟测试中的功能:

monkeypatch.setattr(obj, name, value, raising=True)
monkeypatch.delattr(obj, name, raising=True)
monkeypatch.setitem(mapping, name, value)
monkeypatch.delitem(obj, name, raising=True)
monkeypatch.setenv(name, value, prepend=False)
monkeypatch.delenv(name, raising=True)
monkeypatch.syspath_prepend(path)
monkeypatch.chdir(path)

考虑以下情形:

1.修改测试的函数行为或类的属性,例如,您不会为测试创建API调用或数据库连接,但是您知道预期的输出结果。用于使用monkeypatch.setattr()所需的测试行为来修补功能或属性。这可以包括您自己的功能。使用monkeypatch.delattr()删除用于测试的功能或属性。

2.修改字典的值,例如,您具有要针对某些测试用例进行修改的全局配置。使用monkeypatch.setitem()修补字典进行测试。monkeypatch.delitem()可用于删除项目。

3.修改测试的环境变量,例如在缺少环境变量的情况下测试程序的行为,或为已知变量设置多个值。 monkeypatch.setenv()并monkeypatch.delenv()可以用于这些补丁。

4. 在测试期间,用于修改和 更改当前工作目录的上下文。monkeypatch.setenv(“PATH”, value, prepend=os.pathsep)$PATHmonkeypatch.chdir()

5.使用monkeypatch.syspath_prepend()修改sys.path哪个也会调用pkg_resources.fixup_namespace_packages()和importlib.invalidate_caches()。

monkeypatch类的方法

monkeypatch夹具返回的对象记录了setattr / item / env / syspath的更改。

通过context() 返回一个新MonkeyPatch对象的上下文管理器,该对象with在退出时撤消在块内完成的所有修补操作:

import functools
def test_partial(monkeypatch):with monkeypatch.context() as m:m.setattr(functools, "partial", 3)

在需要在测试结束前撤消某些补丁的情况下很有用,例如stdlib模拟功能,如果被模拟可能会破坏pytest本身

一,设置属性

setattr(target,name,value = ,raising = True )
在目标上设置属性值,记住旧值。默认情况下,如果属性不存在,请引发AttributeError。
该raising值确定如果属性不存在(默认为True,这意味着它将raising )。

为方便起见,您可以指定一个字符串,target该字符串将被解释为点分导入路径,最后一部分是属性名称。
示例: 将设置模块的功能。monkeypatch.setattr(“os.getcwd”, lambda: “/”)getcwdos

delattr(target,name = ,raising = True )
name从中删除属性target,默认情况下,如果属性以前不存在,则引发AttributeError。
如果raising设置为False,则缺少该属性将不会引发异常。

如果未name指定no 并且target它是一个字符串,它将被解释为带点的导入路径,最后一部分是属性名称。

二,设置字典
setitem(dic,name,value )
将字典条目设置name为值。

delitem(dic,name,raising = True )
name从字典中删除。如果它不存在,请引发KeyError。
如果raising设置为False,则如果缺少密钥,则不会引发异常。

三,设置环境
setenv(name,value,prepend = None )
将环境变量设置name为value。如果prepend 是字符,则读取当前环境变量值,并在value相邻的prepend字符前加上该字符。

delenv(name,raising= True )
name从环境中删除。如果它不存在,请引发KeyError。
如果raising设置为False,则缺少环境变量时不会引发异常。

四,其他
syspath_prepend(路径)
前置path到sys.path导入位置列表。

chdir(路径)
将当前工作目录更改为指定的路径。路径可以是字符串或py.path.local对象。

undo()
撤消之前的更改。该调用消耗了撤消堆栈。除非您在撤消调用之后进行更多的猴子修补,否则再次调用它没有任何作用。
通常不需要调用undo(),因为在拆卸过程中会自动调用它。

monkeypatch构建模拟类替代请求接口返回的对象

monkeypatch.setattr()可以与类结合使用,以模拟从函数而不是值返回的对象。想象一个简单的函数来获取API URL并返回json响应。

import requestsdef get_json(url):"""请求一个接口,返回json对象"""r = requests.get(url)return r.json()

r为了测试目的,我们需要模拟返回的响应对象。模拟r需要一个.json()返回字典的方法。可以通过定义一个class来表示在我们的测试文件中r。

class MockResponse:'''定义一个mock类和方法,返回固定json对象'''@staticmethoddef json():return {"mock_key": "mock_response"}def test_get_json(monkeypatch):''' 定义一个mock_get方法,无论传入什么参数,都返回上面的mock类,然后使用monkeypatch.setattr对requests.get重新设置,这样requests.get有了属性 “mock_get”,再次使用时就直接使用了mock_get方法'''def mock_get(*args, **kwargs):return MockResponse()monkeypatch.setattr(requests, "get", mock_get)result = get_json("https://fakeurl")assert result["mock_key"] == "mock_response_1"

执行用例成功:
在这里插入图片描述
monkeypatch将模拟requests.get与我们的mock_get函数一起应用。
该mock_get函数返回MockResponse该类的实例,该类具有json()定义为返回已知测试字典的方法,并且不需要任何外部API连接。可以MockResponse针对要测试的场景以适当的复杂度构建类。

使用fixture:

import pytest
import requestsclass MockResponse:@staticmethoddef json():return {"mock_key": "mock_response"}# monkeypatch操作移到fixture中
@pytest.fixture
def mock_response(monkeypatch):"""Requests.get() mock返回json值: {'mock_key':'mock_response'}."""def mock_get(*args, **kwargs):return MockResponse()monkeypatch.setattr(requests, "get", mock_get)# 注意我们的测试函数传入的是fixture方法,而不是直接传入monkeypatch 
def test_get_json(mock_response):result = app.get_json("https://fakeurl")assert result["mock_key"] == "mock_response"

注意:
建议使用 MonkeyPatch.context()修补程序来限制要测试的块,
该对象with在退出时撤消在块内完成的所有修补操作。

import functoolsdef test_partial(monkeypatch):with monkeypatch.context() as m:m.setattr(functools, "partial", 3)assert functools.partial == 3

猴子补丁字典例子

DEFAULT_CONFIG = {"user": "user1", "database": "db1"}def create_connection_string(config=None):config = config or DEFAULT_CONFIGreturn f"User Id={config['user']}; Location={config['database']};"def test_connection(monkeypatch):monkeypatch.setitem(app.DEFAULT_CONFIG, "user", "test_user")monkeypatch.setitem(app.DEFAULT_CONFIG, "database", "test_db")expected = "User Id=test_user; Location=test_db;"result = app.create_connection_string()assert result == expected

使用monkeypatch.delitem()删除值。

import pytestdef test_missing_user(monkeypatch):monkeypatch.delitem(app.DEFAULT_CONFIG, "user", raising=False)'''因为未传递配置引发KeyError,并且默认值现在缺少“user”项。'''with pytest.raises(KeyError):_ = app.create_connection_string()

这篇关于pytest之Monkeypatching(猴子补丁)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/487028

相关文章

解决Cron定时任务中Pytest脚本无法发送邮件的问题

《解决Cron定时任务中Pytest脚本无法发送邮件的问题》文章探讨解决在Cron定时任务中运行Pytest脚本时邮件发送失败的问题,先优化环境变量,再检查Pytest邮件配置,接着配置文件确保SMT... 目录引言1. 环境变量优化:确保Cron任务可以正确执行解决方案:1.1. 创建一个脚本1.2. 修

基于11GR2的PSU补丁安装

基于11GR2的PSU补丁安装   场景:hp-unix新装数据库11.2.0.4.0,为了便于在线上触发此版本的一些bug而导致停机来维护,在安装后,应用MOS上提供最新的PSU补丁, 操作:利用OPatch工具来打GI和ORACLE软件的PSU 操作系统版本: $ uname -a HP-UX dbsrv B.11.31 U ia64 3837480657unlimited-use

软件测试学习笔记丨Pytest的使用

本文转自测试人社区,原文链接:https://ceshiren.com/t/topic/22158 1. 简介 pytest是一个成熟的全功能python测试框架测试用例的skip和xfail,自动失败重试等处理能够支持简单的单元测试和复杂的功能测试,还可以用来做selenium/appnium等自动化测试,接口自动化测试pytest有很多第三方插件,并且可以自定义扩展,如pytest-

Win 11补丁让AMD成亲儿子,性能最高提升35%

前段时间 AMD 与微软闹出的大瓜大伙儿都恰到了吧?没吃过也没关系,咱们可点击跳转往期内容回味: AMD 官方诉苦,CPU 性能被 Windows 限制 13%! 事情是这么个情况,AMD 不是在上个月先后正式上架了 Zen 5 锐龙 9000 系桌面 CPU 嘛。 来源:AMD 随后有外媒对那几颗 CPU 游戏性能进行了实测,他们发现似乎不管怎么折腾都无法到达官方 PPT 介绍的

Android热补丁动态更新实践

前言 好几个月之前关于Android App热补丁修复火了一把,源于QQ空间团队的一篇文章安卓App热补丁动态修复技术介绍,然后各大厂的开源项目都出来了,本文的实践基于HotFix,也就是QQ空间技术团队那篇文章所应用的技术,笔者会把整个过程的细节和思路在文章中详说,研究这个的出发点也是为了能紧急修复app的bug,而不需要重复发包,不需要用户重新下载app就能把问题解决,个人觉得这个还是蛮

聊聊随机测试和猴子测试

目录 随机测试的特点 1.不可预测性 2.缺乏针对性 3.自动化 4.资源密集型 猴子测试 随机测试 (Random Testing) 猴子测试 (Monkey Testing) 特点: 区别 1.控制程度 2.目标差异 3.实现方式 在我们测试的过程中,通常会使用到随机测试和猴子测试,其中随机测试侧重于人工测试,猴子测试侧重于借助工具执行命令进行测试。 随机测试

猴子排序:一种理论上的排序算法

猴子排序:一种理论上的排序算法 在编程和算法的世界里,总有一些有趣的算法让人忍俊不禁,同时又让人深思。今天,我们来聊聊一种特别的排序算法——猴子排序(Bogosort),也常被戏称为瞎子排序、波加排序或随机排序。这种算法以其独特的方式和极低的效率,成为了一个教学工具和编程娱乐的经典案例。 什么是猴子排序? 猴子排序的基本思想异常简单:通过不断随机地重新排列数组元素,直到数组意外地被排序成正确

pytest实战演练

pytest实战演练 pycharm常见操作 创建项目使用虚拟环境 创建文件夹的时候建议使用的创建方式 这样创建是因为python3.0版本之后导包无区别,之前版本导包会报错的 _init_.py文件中建议为空不写内容 _all_=[]的含义 是将列表中的方法或变量或类暴漏出去便于使用的生效方法,当调用模块中使用 import * 时才生效 联动git使

2024测试开发必知必会:Pytest框架实战!

应用场景: pytest 框架可以解决我们多个测试脚本一起执行的问题。 它提供了测试用例的详细失败信息,使得开发者可以快速准确地改正问题。它兼容最新版本的 Python。它还兼容 unittest、doctest 和 nose,开箱即用。接下来我们详细了解下pytest框架。 01、安装和介绍 概念: pytest 是 python 的一种单元测试框架,同自带的 Unittest 测试框

Python接口自动化测试框架(实战篇)-- 进阶pytest测试框架

文章目录 一、前言二、Pytest和unittest异同2.1、效果展示 三、Pytest框架3.1、环境安装(过程简单)3.2、fixtrue夹具3.3、@pytest.mark.xxx装饰器;3.4、@pytest.mark.skip(season="xxx")3.5、@pytest.mark.parametrize(first,second,third...) 四、总结 一