什么是mock?
mock测试是以可控的方式模拟真实的对象行为。程序员通常创造模拟对象来测试对象本身该具备的行为,很类似汽车设计者使用碰撞测试假人来模拟车辆碰撞中人的动态行为
为什么要使用Mock?
之所以使用mock测试,是因为真实场景很难实现或者短期实现起来很困难。主要场景有:
-
真实对象可能还不存在(接口还没有完成开发)
-
真实对象很难搭建起来(第三方支付联调)
-
真实对象的行为很难触发(例如网络错误)
-
真实对象速度很慢(例如一个完整的数据库,在测试之前可能需要初始化)
-
真实对象可能包含不能用作测试(而不是为实际工作)的信息和方法
-
真实的对象是用户界面,或包括用户页面在内
-
真实的对象使用了回调机制
-
真实对象的行为是不确定的(例如当前的时间或当前的温度)
如何使用Mock?
通过代码制造假的输出(结果)
接口自动化测试客户端Mock
通过代码去模拟假的接口返回数据(访问真实接口的过程就可以省略)
举个栗子:要测试请求接口visit接口,实际上开发还没完成开发工作,我们先编写测试用例,数据都先准备空的,然后可以运行通过,等开发好接口以后,再把相应内容如info中的数据,实际结果等修改后运行
visit方法是在base.py模块中APICase类下
import unittest
from common.base import APICase
class TestRequest(unittest.TestCase, APICase):
def test_request(self):
"""
1.准备接口接口访问的数据
2.调用接口访问visit方法
3.断言
"""
info = {"headers": "", "json": "", "expected": ""}
# actual = self.visit(info)
actual = ""
self.assertEqual(info['expected'], actual)
mock是python的第三方库,所以使用mock前,需要先进行安装pip install mock
修改代码如下:
import unittest
from common.base import APICase
from mock import Mock
class TestRequest(unittest.TestCase, APICase):
def test_request(self):
"""
1.准备接口接口访问的数据
2.调用接口访问visit方法
3.断言
"""
info = {"headers": "", "json": "", "expected": ""}
self.visit = Mock(return_value="")
actual = self.visit(info)
# actual = ""
self.assertEqual(info['expected'], actual)
运行结果:
当接口没开发出来时,直接编写这行代码,因为调用的是mock返回的内容
actual = self.visit(info)
当接口开发完成时,把这行代码注释掉即可
self.visit = Mock(return_value="")
如果想设置返回的数据,也是可以的,如下
拿之前测试注册接口为例,修改代码如下:
import unittest
import requests
from mock import Mock
class TestRegister(unittest.TestCase):
def test_register_01(self):
'''步骤:
1.准备测试数据
2.发送接口请求,得到实际结果
3.预期结果和实际结果的断言
'''
# 1.准备测试数据
url = 'http://api.lemonban.com:8766/futureloan/member/register'
method = 'post'
headers = {'X-Lemonban-Media-Type': 'lemonban.v2'}
json_data = {"mobile_phone": "", "pwd": "12345678"}
expected = {
"code": 1,
"msg": "手机号为空",
"data": None,
"copyright": "Copyright 柠檬班 © 2017-2020 湖南省零檬信息技术有限公司 All Rights Reserved"
}
# 2.发送接口请求,得到实际结果
# 因为执行了Mock,所以就不会执行请求真实的接口了
requests.request = Mock(return_value=expected)
response = requests.request(method=method, url=url, headers=headers, json=json_data)
# mock返回的是expected的内容,因此是dict,所以实际结果要把之前代码上的.json去掉
actual = response
# 3.预期结果和实际结果的断言
self.assertEqual(expected, actual)
只需要修改两处代码,即可访问假的接口
加上下面这行代码
requests.request = Mock(return_value=expected)
修改下面这行代码
actual = response.json()
修改为 actual = response
服务Mock(Mock Server)
方法一:
开发的接口是在server,真实的服务器
我就自己冒充开发人员,写一个假的服务器,写一个假的接口,可以通过mockoon工具实现
直接去官网下载安装即可
打开mockoon,设置请求方法、URL、返回内容,点击开启服务按钮
这时候就可以请求服务接口了
方法二:
测试开发技术,自己做一个真实的服务出来,确实可以支持更多的响应,会省略很多步骤
用代码编写一个服务接口
from flask import Flask
app = Flask("py44")
@app.route('/member/register', methods=['post'])
def register():
return {"code": 11, "msg": "success"}
app.run(debug=True)
运行结果:
只有运行代码,才算开启服务
这时候就可以请求服务接口了
方法2的灵活之处就是可以支持更多响应,如设置请求体
from flask import Flask, request
app = Flask("py44")
@app.route('/member/register', methods=['post'])
def register():
username = request.form.get('username')
password = request.form.get('password')
if username == 'momo' and password == '123456':
return {"code": 11, "msg": "success"}
return {"code": 22, "msg": "failed"}
app.run(debug=True)
启动服务后,使用postman请求