前言
今天跟小伙伴们一起来学习一下如何编写Python脚本进行mock测试。
什么是mock?
-
测试桩,模拟被测对象的返回,用于测试
-
通常意义的mock指的就是mock server, 模拟服务端返回的接口数据,用于前端开发,第三方接口联调
为什么要mock?
1. 解决依赖问题:当我们测试一个接口或者功能模块的时候,如果这个接口或者功能模块依赖其他接口或其他模块,那么如果所依赖的接口或功能模块未开发完毕,那么我们就可以使用mock模拟被依赖接口,完成目标接口的测试。
2.单元测试:如果某个功能未开发完成,我们又要进行测试用例的代码编写,我们也可以先模拟这个功能进行测试
3.模拟复杂业务的接口:实际工作中如果我们在测试一个接口功能时,如果这个接口依赖一个非常复杂的接口业务,那么我们完全可以使用mock来模拟这个复杂的业务接口,其实 这个和解决接口依赖是一样的原理。
4.前后端联调:如果你是一个前端页面开发,现在需要开发一个功能:根据后台返回的状态展示不同的页面,那么你就需要调用后台的接口,但是后台接口还未开发完成,可以借助mock来模拟后台这个接口返回你想要的数据。
如何mock?
1.利用抓包工具比如fiddler
2.可以利用web框架模拟,Django Flask ---python web开发框架,Flask的特点就是,结构简单,容易入门
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
import random import time from flask import Flask,request,json #实例化一个web服务对象 app = Flask(__name__) #创建一个方法来处理请求 #定义一个路由--访问服务的根目录就可以得到结果 @app .route( '/' ) def hello(): return '<h1>hello flask</h1>' #构造一个接受post请求的响应 @app .route( '/post' ,methods = [ 'POST' ]) def test_post(): #处理接口发送过来的两个参数,将两个参数合并成一个字符串返回 d1 = request.form[ 'd1' ] d2 = request.form[ 'd2' ] return d1 + d2 if __name__ = = '__main__' : #运行服务,并确定服务运行的IP和端口 app.run( '127.0.0.1' , '9090' ) |
启动mock服务端:
客户端代码:
import requests
1
2
3
4
5
6
|
body = { 'd1' : 'hi' , 'd2' : 'falsk12312312' } resp = requests.post( 'http://127.0.0.1:9090/post' ,data = body) print (resp.text) |
结果如下:
二:mock接口测试实战案例
接口文档如下:
极简交易支付接口
接口路径: /trade/purchase
请求方式: POST
请求参数:
参数 |
类型 |
是否必填 |
最大长度 |
描述 |
示例值 |
out_trade_no |
String |
是 |
64 |
商户订单号,64个符以内、可包含字母、数字、下划线;需保证在商户端不重复
|
20150320010101001 |
auth_code |
String |
是 |
64 |
支付授权码,25~30开头的长度为16~24位的数字,实际字符串长度以开发者获取的付款码长度为准
|
28763443825664394 |
subject |
String |
是 |
356 |
订单标题 |
Iphone6 16G |
buyer_id |
String |
否 |
28 |
买家的支付宝用id,如果为空,会从传入的码值信息中获取买家 ID |
2088202954065786 |
seller_id |
String |
否 |
28 |
如果该值为空,则默认为商户签约账号对应的支付宝用户ID
|
2088102146225135 |
total_amount |
Price |
否 |
11 |
订单总金额,单位为元,精确到小数点后两位,取值范围[0.01,100000000] 如果同时传入【可打折金额】和【不可打折金 额】,该参数可以不用传入;如果同时传入了 【可打折金额】,【不可打折金额】,【订单总金额】三者,则必须满足如下条件:【订单总金额】=【可打折金额】+【不可打折金额】
|
88.88 |
响应参数:
请求头:键:Content-Type 值:application/json
请求示例:
{
'out_trade_no':'20150320010101001',
'auth_code':'28763443825664394',
'buyer_id':'2088202954065786',
'seller_id':'2088102146225135',
'subject':'Iphone6',
'total_amount':'88.88',
}
成功返回示例:
失败返回示例:
{'error': {'password': '密码错误'}, 'success': 'false'}
搭建mock服务端:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
import random import time from flask import Flask,request,json #实例化一个web服务对象 app = Flask(__name__) #创建一个方法来处理请求 #定义一个路由--访问服务的根目录就可以得到结果 #构造一个接受post请求的响应 #处理极简交易接口 @app .route( '/trade/purchase' ,methods = [ 'POST' ]) def purchase(): #拿到客户端返回的数据 res = json.loads(request.get_data()) out_trade_no = res[ 'out_trade_no' ] auth_code = res[ 'auth_code' ] data = { 'code' : '40004' , 'msg' : 'Business Failed' , 'sub_code' : 'ACQ.TRADE_HAS_SUCCESS' , 'sub_msg' : '交易已被支付' , 'trade_no' : '2013112011001004330000121536' , 'out_trade_no' : '6823789339978248' } #把out_trade_no改成客户端发送过来的数据 data[ 'out_trade_no' ] = out_trade_no data[ 'trade_no' ] = time.strftime( '%Y%m%d%H%M%S' ) + str (random.random()).replace( '0.' ,'') #验证授权码 if auth_code ! = '28763443825664394' : return { 'coode' : '50000' , 'msg' : '请求码验证失败' } return data if __name__ = = '__main__' : #运行服务,并确定服务运行的IP和端口 app.run( '127.0.0.1' , '9090' ) |
客户端代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
#利用request发送post请求给服务端 import requests data = { 'out_trade_no' : '20150320010101001' , 'auth_code' : '2876344382566439' , 'buyer_id' : '2088202954065786' , 'seller_id' : '2088102146225135' , 'subject' : 'Iphone6' , 'total_amount' : '88.88' , } resp = requests.post( 'http://127.0.0.1:9090/trade/purchase' ,json = data) print (resp.json()) |
返回结果如下:
这样就完成了mock接口测试了,小伙伴们学会了吗?