python接口测试,mock模块基本使用介绍
mock简介
- py3已将mock集成到unittest库中
- 为的就是更好的进行单元测试
- 简单理解,模拟接口返回参数
- 通俗易懂,直接修改接口返回参数的值
- 官方文档:https://docs.python.org/zh-cn/3/library/unittest.mock.html
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实际使用
一个未开发完成的功能如何测试?
def add(self, a, b):
"""两个数相加"""
pass class TestSub(unittest.TestCase):
"""测试两个数相加用例""" def test_sub(self):
# 创建一个mock对象 return_value代表mock一个数据
mock_add = mock.Mock(return_value=15)
# 将mock对象赋予给被测函数
add = mock_add
# 调用被测函数
result = add(5, 5)
# 断言实际结果和预期结果
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时会返回不同的值;如下
mock_obj = mock.Mock(side_effect= [1,2,3])
print(mock_obj())
print(mock_obj())
print(mock_obj())
print(mock_obj()) # 输出
Traceback (most recent call last):
1
File "D:/MyThreading/mymock.py", line 37, in <module>
2
print(mock_obj())
3
File "C:\Python36\lib\unittest\mock.py", line 939, in __call__
return _mock_self._mock_call(*args, **kwargs)
File "C:\Python36\lib\unittest\mock.py", line 998, in _mock_call
result = next(effect)
StopIteration
存在依赖关系的功能如何测试?
# 支付类
class Payment: def requestOutofSystem(self, card_num, amount):
'''
请求第三方外部支付接口,并返回响应码
:param card_num: 卡号
:param amount: 支付金额
:return: 返回状态码,200 代表支付成功,500 代表支付异常失败
'''
# 第三方支付接口请求地址(故意写错)
url = "http://third.payment.pay/"
# 请求参数
data = {"card_num": card_num, "amount": amount}
response = requests.post(url, data=data)
# 返回状态码
return response.status_code def doPay(self, user_id, card_num, amount):
'''
支付
:param userId: 用户ID
:param card_num: 卡号
:param amount: 支付金额
:return:
'''
try:
# 调用第三方支付接口请求进行真实扣款
resp = self.requestOutofSystem(card_num, amount)
print('调用第三方支付接口返回结果:', resp)
except TimeoutError:
# 如果超时就重新调用一次
print('重试一次')
resp = self.requestOutofSystem(card_num, amount) if resp == 200:
# 返回第三方支付成功,则进行系统里面的扣款并记录支付记录等操作
print("{0}支付{1}成功!!!进行扣款并记录支付记录".format(user_id, amount))
return 'success' elif resp == 500:
# 返回第三方支付失败,则不进行扣款
print("{0}支付{1}失败!!不进行扣款!!!".format(user_id, amount))
return 'fail' # 单元测试类
class payTest(unittest.TestCase): def test_pay_success(self):
pay = Payment()
# 模拟第三方支付接口返回200
pay.requestOutofSystem = mock.Mock(return_value=200)
resp = pay.doPay(user_id=1, card_num='', amount=100)
self.assertEqual('success', resp) def test_pay_fail(self):
pay = Payment()
# 模拟第三方支付接口返回500
pay.requestOutofSystem = mock.Mock(return_value=500)
resp = pay.doPay(user_id=1, card_num='', amount=100)
self.assertEqual('fail', resp) def test_pay_time_success(self):
pay = Payment()
# 模拟第三方支付接口首次支付超时,重试第二次成功
pay.requestOutofSystem = mock.Mock(side_effect=[TimeoutError, 200])
resp = pay.doPay(user_id=1, card_num='', amount=100)
self.assertEqual('success', resp) def test_pay_time_fail(self):
pay = Payment()
# 模拟第三方支付接口首次支付超时,重试第二次失败
pay.requestOutofSystem = mock.Mock(side_effect=[TimeoutError, 500])
resp = pay.doPay(user_id=1, card_num='', amount=100)
self.assertEqual('fail', resp)
也许有小伙伴会问,第三方支付都不能用,我们的测试结果是否是有效的呢?
通常在测试一个模块的时候,是可以认为其他模块的功能是正常的,只针对目标模块进行测试是没有任何问题的,所以说测试结果也是正确的
mock装饰器
一共两种格式
- @patch('module名字.方法名')
- @patch.object(类名, '方法名')
# 装饰类演示
from mock import Mock, patch # 单独的相乘函数
def multiple(a, b):
return a * b # 单独的捕获Exception函数
def is_error():
try:
os.mkdir("")
return False
except Exception as e:
return True # 计算类,包含add方法
class calculator(object):
def add(self, a, b):
return a + b # 装饰类演示 - 单元测试类
class TestProducer(unittest.TestCase): # case执行前
def setUp(self):
self.calculator = calculator() # mock一个函数,注意也要指定module
@patch('mock_learn.multiple')
def test_multiple(self, mock_multiple):
mock_multiple.return_value = 3
self.assertEqual(multiple(8, 14), 3) # mock一个类对象的方法
@patch.object(calculator, 'add')
def test_add(self, mock_add):
mock_add.return_value = 3
self.assertEqual(self.calculator.add(8, 14), 3) # mock调用方法返回多个不同的值
@patch.object(calculator, 'add')
def test_effect(self, mock_add):
mock_add.side_effect = [1, 2, 3]
self.assertEqual(self.calculator.add(8, 14), 1)
self.assertEqual(self.calculator.add(8, 14), 2)
self.assertEqual(self.calculator.add(8, 14), 3) # mock的函数抛出Exception
@patch('os.mkdir')
def test_exception(self, mkdir):
mkdir.side_effect = Exception
self.assertEqual(is_error(), True) # mock多个函数,注意函数调用顺序
@patch.object(calculator, 'add')
@patch('mock_learn.multiple')
def test_more(self, mock_multiple, mock_add):
mock_add.return_value = 1
mock_multiple.return_value = 4
self.assertEqual(self.calculator.add(3, 3), 1)
self.assertEqual(multiple(3, 3), 4)
python接口测试,mock模块基本使用介绍的更多相关文章
- python之mock模块基本使用
mock简介 mock原来是python的第三方库 python3以后mock模块已经整合到了unittest测试框架中,不用再单独安装 Mock这个词在英语中有模拟的这个意思,因此我们可以猜测出这个 ...
- (数据科学学习手札32)Python中re模块的详细介绍
一.简介 关于正则表达式,我在前一篇(数据科学学习手札31)中已经做了详细介绍,本篇将对Python中自带模块re的常用功能进行总结: re作为Python中专为正则表达式相关功能做出支持的模块,提供 ...
- [转] Python 常用第三方模块 及PIL介绍
原文地址 除了内建的模块外,Python还有大量的第三方模块. 基本上,所有的第三方模块都会在PyPI - the Python Package Index上注册,只要找到对应的模块名字,即可用pip ...
- Python的getpass模块
Python的getpass模块 目录 简单介绍 getpass() getuser() 简单介绍 getpass模块提供了两个函数: getpass() 获取输入的密码,并且输入内容屏幕不显示,和L ...
- Python接口测试实战5(下) - RESTful、Web Service及Mock Server
如有任何学习问题,可以添加作者微信:lockingfree 课程目录 Python接口测试实战1(上)- 接口测试理论 Python接口测试实战1(下)- 接口测试工具的使用 Python接口测试实战 ...
- Python 的mock模拟测试介绍
如何不靠耐心测试 可能我们正在写一个社交软件并且想测试一下"发布到Facebook的功能",但是我们不希望每次运行测试集的时候都发布到Facebook上. Python的unitt ...
- python mock模块使用(一)
什么是mock unittest.mock是一个用于在Python中进行单元测试的库,Mock翻译过来就是模拟的意思,顾名思义这个库的主要功能是模拟一些东西. 它的主要功能是使用mock对象替代掉指定 ...
- 使用Python中的mock模块进行单元测试
在进行单元测试的时候,有时候会遇到这种情况: 出于某些原因,我们不想测试某一部分内容,但是我们想要测试的部分却依赖这部分内容. 这时候,可以使用mock模块来模拟调用这部分内容,并给出返回结果,举例如 ...
- {python之IO多路复用} IO模型介绍 阻塞IO(blocking IO) 非阻塞IO(non-blocking IO) 多路复用IO(IO multiplexing) 异步IO(Asynchronous I/O) IO模型比较分析 selectors模块
python之IO多路复用 阅读目录 一 IO模型介绍 二 阻塞IO(blocking IO) 三 非阻塞IO(non-blocking IO) 四 多路复用IO(IO multiplexing) 五 ...
随机推荐
- 备战省赛组队训练赛第十四场(UPC)
codeforces:传送门 upc:传送门 外来题解: [1]:https://blog.csdn.net/ccsu_cat/article/details/86707446 [2]:https:/ ...
- iview table中的render函数使用
1.表格列数据内容过多可以用以下两个属性解决: ellipsis:"true', tooltip:true 使每个列的内容如果过多的话变为省略号 2.table中的render函数(实现根据 ...
- 浅解 go 语言的 interface(许的博客)
我写了一个 go interface 相关的代码转换为 C 代码的样例.也许有助于大家理解 go 的 interface.不过请注意一点,这里没有完整解析 go 语言 interface 的所有细节. ...
- lombok优缺点
优点: 能通过注解的形式自动生成构造器.getter/setter.equals.hashcode.toString等方法,提高了一定的开发效率 让代码变得简洁,不用过多的去关注相应的方法 属性做修改 ...
- Rust入坑指南:亡羊补牢
如果你已经开始学习Rust,相信你已经体会过Rust编译器的强大.它可以帮助你避免程序中的大部分错误,但是编译器也不是万能的,如果程序写的不恰当,还是会发生错误,让程序崩溃.所以今天我们就来聊一聊Ru ...
- Redis的高并发、持久化、高可用架构设计
就是如果你用redis缓存技术的话,肯定要考虑如何用redis来加多台机器,保证redis是高并发的,还有就是如何让Redis保证自己不是挂掉以后就直接死掉了,redis高可用 我这里会选用我之前讲解 ...
- javascript DOM 编程艺术 札记1
一个重要观点 DOM 是指 文档对象模型,它对应浏览器实际认知的东西.html 文本本身和 html 加载到浏览器中显示的东西并不是完全一致的,后者就是 DOM 节点树,它是浏览器实际认知的东西.一个 ...
- 从零开始のcocos2dx生活(二)Node
节点 Node 文章目录 节点 Node 前言 变量初始化 创建一个节点对象 获取节点依赖的计数器 获取节点的描述(获取节点的Tag) 节点的局部层顺序值(LocalZOrder) 设置节点的Loca ...
- vue实现下拉框全选和输入匹配
实际项目中的一个需求: 点击文本框,弹出带有复选框的选项,然后获取选中项的数据,传给后面的一个功能.在文本框输入内容,也会动态的匹配下拉列表,并且列表带有全选功能. 朴素的效果图: 我选择了用vue实 ...
- 【题解】BZOJ4241: 历史研究(魔改莫队)
[题解]BZOJ4241: 历史研究(魔改莫队) 真的是好题啊 题意 给你一个序列和很多组询问(可以离线),问你这个区间中\(\max\){元素出现个数\(\times\)元素权值} IOI国历史研究 ...