【Python自动化测试】mock模块基本使用介绍

news2024/11/19 16:33:38

mock简介

  • py3已将mock集成到unittest库中
  • 为的就是更好的进行单元测试
  • 简单理解,模拟接口返回参数
  • 通俗易懂,直接修改接口返回参数的值
  • 官方文档:unittest.mock --- 模拟对象库 — Python 3.11.4 文档

mock作用
解决依赖问题,达到解耦作用
当我们测试某个目标接口(模块)时,该接口依赖其他接口,当被依赖的接口未开发完成时,可以用mock模拟被依赖接口,完成目标接口的测试

模拟复杂业务的接口
当我们测试某个目标接口(模块),该接口依赖一个非常复杂的接口时,可以用mock来模拟这个复杂的业务接口;也解决接口依赖一样的原理

单元测试
如果某个接口(模块)未开发完成时,又需要编写测试用例,则可以通过mock模拟该接口(模块)进行测试

前后端联调
前端开发的页面需要根据后端返回的不同状态码展示不同的页面,当后端接口未开发完成时,也可通过mock来模拟后端接口返回自己想要的数据

mock类解读
class Mock(spec=None,side_effect=None,return_value=DEFFAULT,name=None) 

secp:定义mock对象的属性值,可以是列表,字符串,甚至一个对象或者实例 
side_effect:可以用来抛出异常或者动态改变返回值,它必须是一个iterator(列表),它会覆盖return_value
return_value:定义mock方法的返回值,它可以是一个值,可以是一个对象(如果存在side_effect参数那这个就没有用,也就是不能同时用)
name:作为mock对象的一个标识,在print时可以看到
mock实际使用
一个未开发完成的功能如何测试?

 1 def add(self, a, b):
 2     """两个数相加"""
 3     pass
 4 
 5 
 6 class TestSub(unittest.TestCase):
 7     """测试两个数相加用例"""
 8 
 9     def test_sub(self):
10         # 创建一个mock对象 return_value代表mock一个数据
11         mock_add = mock.Mock(return_value=15)
12         # 将mock对象赋予给被测函数
13         add = mock_add
14         # 调用被测函数
15         result = add(5, 5)
16         # 断言实际结果和预期结果
17         self.assertEqual(result, 15)
一个完成开发的功能如何测试?

class SubClass(object):
    def add(self, a, b):
        """两个数相加"""
        return a + b
 
 
class TestSub(unittest.TestCase):
    """测试两个数相加用例"""
 
 
    def test_add2(self):
        # 初始化被测函数类实例
        sub = SubClass()
        # 创建一个mock对象 return_value代表mock一个数据
        # 传递side_effect关键字参数, 会覆盖return_value参数值, 使用真实的add方法测试
        sub.add = Mock(return_value=15, side_effect=sub.add)
        # 调用被测函数
        result = sub.add(5, 5)
        # 断言实际结果和预期结果
        self.assertEqual(result, 10)

side_effect:这里给的参数值是sub.add相当于add方法的地址,当我们调用add方法时就会调用真实的add方法

简单理解成:传递了side_effect参数且值为被测函数地址时,mock不会起作用;两者不可共存

另外,side_effect接受的是一个可迭代序列,当传递多个值时,每次调用mock时会返回不同的值;如下

 1 mock_obj = mock.Mock(side_effect= [1,2,3])
 2 print(mock_obj())
 3 print(mock_obj())
 4 print(mock_obj())
 5 print(mock_obj())
 6 
 7 # 输出
 8 Traceback (most recent call last):
 9 1
10   File "D:/MyThreading/mymock.py", line 37, in <module>
11 2
12     print(mock_obj())
13 3
14   File "C:\Python36\lib\unittest\mock.py", line 939, in __call__
15     return _mock_self._mock_call(*args, **kwargs)
16   File "C:\Python36\lib\unittest\mock.py", line 998, in _mock_call
17     result = next(effect)
18 StopIteration
存在依赖关系的功能如何测试?
 1 # 支付类
 2 class Payment:
 3 
 4     def requestOutofSystem(self, card_num, amount):
 5         '''
 6         请求第三方外部支付接口,并返回响应码
 7         :param card_num: 卡号
 8         :param amount: 支付金额
 9         :return: 返回状态码,200 代表支付成功,500 代表支付异常失败
10         '''
11         # 第三方支付接口请求地址(故意写错)
12         url = "http://third.payment.pay/"
13         # 请求参数
14         data = {"card_num": card_num, "amount": amount}
15         response = requests.post(url, data=data)
16         # 返回状态码
17         return response.status_code
18 
19     def doPay(self, user_id, card_num, amount):
20         '''
21         支付
22         :param userId: 用户ID
23         :param card_num: 卡号
24         :param amount: 支付金额
25         :return:
26         '''
27         try:
28             # 调用第三方支付接口请求进行真实扣款
29             resp = self.requestOutofSystem(card_num, amount)
30             print('调用第三方支付接口返回结果:', resp)
31         except TimeoutError:
32             # 如果超时就重新调用一次
33             print('重试一次')
34             resp = self.requestOutofSystem(card_num, amount)
35 
36         if resp == 200:
37             # 返回第三方支付成功,则进行系统里面的扣款并记录支付记录等操作
38             print("{0}支付{1}成功!!!进行扣款并记录支付记录".format(user_id, amount))
39             return 'success'
40 
41         elif resp == 500:
42             # 返回第三方支付失败,则不进行扣款
43             print("{0}支付{1}失败!!不进行扣款!!!".format(user_id, amount))
44             return 'fail'
45 
46 # 单元测试类
47 class payTest(unittest.TestCase):
48 
49     def test_pay_success(self):
50         pay = Payment()
51         # 模拟第三方支付接口返回200
52         pay.requestOutofSystem = mock.Mock(return_value=200)
53         resp = pay.doPay(user_id=1, card_num='12345678', amount=100)
54         self.assertEqual('success', resp)
55 
56     def test_pay_fail(self):
57         pay = Payment()
58         # 模拟第三方支付接口返回500
59         pay.requestOutofSystem = mock.Mock(return_value=500)
60         resp = pay.doPay(user_id=1, card_num='12345678', amount=100)
61         self.assertEqual('fail', resp)
62 
63     def test_pay_time_success(self):
64         pay = Payment()
65         # 模拟第三方支付接口首次支付超时,重试第二次成功
66         pay.requestOutofSystem = mock.Mock(side_effect=[TimeoutError, 200])
67         resp = pay.doPay(user_id=1, card_num='12345678', amount=100)
68         self.assertEqual('success', resp)
69 
70     def test_pay_time_fail(self):
71         pay = Payment()
72         # 模拟第三方支付接口首次支付超时,重试第二次失败
73         pay.requestOutofSystem = mock.Mock(side_effect=[TimeoutError, 500])
74         resp = pay.doPay(user_id=1, card_num='12345678', amount=100)
75         self.assertEqual('fail', resp)

也许有小伙伴会问,第三方支付都不能用,我们的测试结果是否是有效的呢?

通常在测试一个模块的时候,是可以认为其他模块的功能是正常的,只针对目标模块进行测试是没有任何问题的,所以说测试结果也是正确的

mock装饰器
一共两种格式

 @patch('module名字.方法名') 
 @patch.object(类名, '方法名') 

 1 # 装饰类演示
 2 from mock import Mock, patch
 3 
 4 
 5 # 单独的相乘函数
 6 def multiple(a, b):
 7     return a * b
 8 
 9 
10 # 单独的捕获Exception函数
11 def is_error():
12     try:
13         os.mkdir("11")
14         return False
15     except Exception as e:
16         return True
17 
18 
19 # 计算类,包含add方法
20 class calculator(object):
21     def add(self, a, b):
22         return a + b
23 
24 
25 # 装饰类演示 - 单元测试类
26 class TestProducer(unittest.TestCase):
27 
28     # case执行前
29     def setUp(self):
30         self.calculator = calculator()
31 
32     # mock一个函数,注意也要指定module
33     @patch('mock_learn.multiple')
34     def test_multiple(self, mock_multiple):
35         mock_multiple.return_value = 3
36         self.assertEqual(multiple(8, 14), 3)
37 
38     # mock一个类对象的方法
39     @patch.object(calculator, 'add')
40     def test_add(self, mock_add):
41         mock_add.return_value = 3
42         self.assertEqual(self.calculator.add(8, 14), 3)
43 
44     # mock调用方法返回多个不同的值
45     @patch.object(calculator, 'add')
46     def test_effect(self, mock_add):
47         mock_add.side_effect = [1, 2, 3]
48         self.assertEqual(self.calculator.add(8, 14), 1)
49         self.assertEqual(self.calculator.add(8, 14), 2)
50         self.assertEqual(self.calculator.add(8, 14), 3)
51 
52     # mock的函数抛出Exception
53     @patch('os.mkdir')
54     def test_exception(self, mkdir):
55         mkdir.side_effect = Exception
56         self.assertEqual(is_error(), True)
57 
58     # mock多个函数,注意函数调用顺序
59     @patch.object(calculator, 'add')
60     @patch('mock_learn.multiple')
61     def test_more(self, mock_multiple, mock_add):
62         mock_add.return_value = 1
63         mock_multiple.return_value = 4
64         self.assertEqual(self.calculator.add(3, 3), 1)
65         self.assertEqual(multiple(3, 3), 4)

 下面是配套学习资料,对于做【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1046567.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

软件测试/测试开发 | AI大模型应用开发实训营来啦~ 大模型学习资料免费领

因为 AIGC 持续火热&#xff0c;越来越多的企业都需要借助大模型来为自己的业务赋能&#xff0c;也就是产出适合自己公司业务情况的智能化产品&#xff0c;这是目前程序员必须要面对的难题和挑战。如果要在企业内部落地相关引用&#xff0c;就需要员工具备响应的大模型应用开发…

LCR 101. 分割等和子集——力扣——背包问题、动态规矩

问题描述 代码展示 class Solution:def canPartition(self, nums: List[int]) -> bool:if len(nums) < 1:return Falsetotal_sum sum(nums)if total_sum % 2 ! 0: # 总和为奇数&#xff0c;无法分成两个相等的子集return Falsetarget_sum total_sum // 2dp [[False]…

el-tooltip内容换行显示

效果图&#xff1a; html: <div class"rules-tooltip flex-center"><el-tooltip class"item" effect"dark" placement"bottom-start"><div slot"content" v-html"tipsContent"></div>&l…

工具篇 | WSL使用入门教程以及基于WSL和natApp内网穿透实践 - 对比VMWare

介绍 在开发工具中&#xff0c;Windows Subsystem for Linux (WSL) 和 VMWare 它们都可以实现了在 Windows 上运行 Linux系统。 文章概览 WSL Vs VMWare 我们将简单比对 WSL 和 VMWare&#xff0c;在性能、资源消耗等方面的差异&#xff0c;以协助您做出更加明确的选择。 …

专业级操作,如何快速批量虚化多个视频的背景边框

如果你是一名视频编辑爱好者&#xff0c;或者是一名需要处理大量视频素材的专业人士&#xff0c;那么你可能会对如何快速处理和虚化视频的背景边框感到困惑。这里&#xff0c;我们就为你提供一种方法&#xff0c;使用固乔剪辑助手工具&#xff0c;你可以轻松实现批量虚化多个视…

ATA-8000系列射频功率放大器——应用场景介绍

ATA-8000系列是一款射频功率放大器。其P1dB输出功率500W&#xff0c;饱和输出功率最大1000W。增益数控可调&#xff0c;一键保存设置&#xff0c;提供了方便简洁的操作选择&#xff0c;可与主流的信号发生器配套使用&#xff0c;实现射频信号的放大。 图&#xff1a;ATA-8000系…

Kubernetes基本概念简介

零 引入 在传统的应用程序部署中&#xff0c;需要手动配置和管理服务器、网络和存储等基础设施&#xff0c;并且随着应用程序规模的增长&#xff0c;管理复杂性也会大大增加。Kubernetes通过自动化和抽象化的方式&#xff0c;解决了这些挑战&#xff0c;使得应用程序可以以一种…

sdk下载慢的解决办法

Android studio版本&#xff1a;为Android Studio 4.1.1&#xff0c; 先完成Android Studio软件安装&#xff0c;打开Android Studio&#xff0c;点击File -> settings->Android SDK&#xff0c;按照开发需要安装sdk platform、SDK Tools工具。 sdk下载慢解决办法 1、…

Nuxt 菜鸟入门学习笔记六:路由

文章目录 路由 Routing页面 Pages导航 Navigation路由参数 Route Parameters路由中间件 Route Middleware路由验证 Route Validation Nuxt 官网地址&#xff1a; https://nuxt.com/ 路由 Routing Nuxt 的一个核心功能是文件系统路由器。pages/目录下的每个 Vue 文件都会创建一…

【ACL2023】Event Extraction as Question Generation and Answering

论文题目&#xff1a;Event Extraction as Question Generation and Answering 论文来源&#xff1a;ACL2023 论文链接&#xff1a;Event Extraction as Question Generation and Answering - ACL Anthology 代码链接&#xff1a;GitHub - dataminr-ai/Event-Extraction-as-…

PowerDsigner 数据库逆向pdm数模 常见数据库连接问题

本文章记录本人在使用powerdsigner工具&#xff0c;反向工程生成项目数据库表结构以及表关系的过程中遇到的两个常见问题。 问题1&#xff1a;Could not Initialize JavaVM 问题2&#xff1a;Non SQL Error : Could not load class oracle.jdbc.OracleDriver 环境&#xff1…

枚举enum

使用enum关键字定义提供枚举类的对象&#xff0c;多个对象用逗号分开&#xff0c;结尾用分号结束提供构造方法&#xff0c;给属性赋值使用public statiac final来修饰是属性提供get方法提供toString方法 public enum Season {SPRING("春天", "春暖花开"),…

都用HTTPS了,还能被查出浏览记录?

最近&#xff0c;群里一个刚入职的小伙因为用公司电脑访问奇怪的网站&#xff0c;被约谈了。他很困惑 —— 访问的都是HTTPS的网站&#xff0c;公司咋知道他访问了啥&#xff1f; 实际上&#xff0c;由于网络通信有很多层&#xff0c;即使加密通信&#xff0c;仍有很多途径暴露…

达梦数据库使用杂记

1、DM管理工具打开后一片白 这是因为上一次把对象导航窗口手动关闭了&#xff0c;后面再重新打开时默认就不显示了&#xff1b; 只需要到窗口-视图-对象导航 打开即可 2、 查询语句需要带表空间名&#xff0c;如&#xff1a;select * from "表空间名"."表名&…

混合IT基础设施的安全挑战与缓解策略

自从“身份是新的边界”这句格言问世以来&#xff0c;公司已经开始扩展他们的能力和运营&#xff0c;超越了基于本地、办公室基础设施的范围。采用云原生技术意味着组织正在寻求扩大传统工作流程&#xff0c;而无需投入时间和资源来建立物理数据中心和其他硬件基础设施。 身份…

2023版 STM32实战4 滴答定时器精准延时

SysTick简介与特性 -1- SysTick属于系统时钟。 -2- SysTick定时器被捆绑在NVIC中。 -3- SysTick可以产生中断,且中断不可屏蔽。 SysTick的时钟源查看 通过时钟树可以看出滴答的时钟最大为72MHZ/89MHZ 通过中文参考手册也可以得到这个结论 代码编写&#xff08;已经验证&a…

苹果曾考虑基于定位控制AirPods Pro自适应音频

在一次最近的采访中&#xff0c;苹果公司的高管Ron Huang和Eric Treski透露&#xff0c;他们在开发AirPods Pro自适应音频功能时&#xff0c;曾考虑使用GPS信号来控制音频级别。这个有趣的细节打破了我们对AirPods Pro的固有认知&#xff0c;让我们对苹果的创新思维有了更深的…

十三,打印辐照度图

上节HDR环境贴图进行卷积后&#xff0c;得到的就是辐照度图&#xff0c;表示的是周围环境间接漫反射光的积分。 现在也进行下打印&#xff0c;和前面打印HDR环境贴图一样&#xff0c;只是由于辐照度图做了平均&#xff0c;失去了大量高频部分&#xff0c;因此&#xff0c;可以…

unity 限制 相机移动 区域(无需碰撞检测)

限制功能原著地址&#xff1a;unity限制相机可移动区域&#xff08;box collider&#xff09;_unity限制相机移动区域_manson-liao的博客-CSDN博客 一、创建限制区域 创建一个Cube&#xff0c;Scale大小1&#xff0c;添加组件&#xff1a;BoxCollder&#xff0c;调整BoxColld…

花式打印0~100中3的倍数

列表解析3的倍数负步长切片倒序&#xff0c;iter、zip函数配合实现分行格式打印。 (本笔记适合熟悉python列表解析式的 coder 翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org/ Free&#xff1a;大咖免费“圣经”教程《 python 完全自学教程…