python接口测试实战_Python接口测试实战5(下) - RESTful、Web Service及Mock Server

课程目录

更多学习资料请加添加作者微信:superz-han获取

本节内容

REST及RESTful API

Web Service

XML解析

Mock Server

REST及RESTful API

REST:表述性状态转移或表现层状态转移,“表现”及每个接口地址(URI)都表现为(视为)一个资源对象(文本资源、图片资源、服务资源),状态转移指通过POST/PUT方法发送完整的新状态信息来更改资源对象的状态

如某https://api.***.com/user资源状态为{"name": "Kaka", "age": 30},我们通过POST/PUT请求发送新状态{"name": "Kaka", "age": 18}来更新对象信息,完成状态转移

URI 与URL的区别:URL值包含协议的链接,如https://www.baidu.com, 还有一种相对链接叫URN,如/doc/1.html,这两种都能唯一定位一个资源,URI(统一资源定位符)包含URL和URN

RESTful API是一种接口设计风格或规范,主要有以下特点:

统一使用https协议

接口使用专用的api域名 https://api.example.com/

接口分版本管理 https://api.example.com/v1/

路径又称"终点"(endpoint),表示API的具体网址,路径中只能包含名词(代表资源对象),可以使用复数来代表多个一个资源集合https://api.example.com/v1/zoos

同一个接口提供多种请求方法,GET获取资源信息,POST新建或更新资源,PUT/PATCH更新资源,DELETE删除资源

可以通过url参数过滤信息 https://api.example.com/v1/zoos?limit=10 # 获取前10个

尽量使用JSON, 避免使用XML

身份认证推荐使用OAuth2.0,或Basic Auth,token等,避免使用Cookie和Session(RESTful强调无状态的设计)

示例:

https://api.github.com

授权 Basic Auth (superhin001, ***) 或 Oauth 2.0 Access Token: 1c4f679300f29ee4e7041028d49e504b9da145b1

5dd299c23eb0

GET https://api.github.com/user

5dd299c23eb0

POST https://api.github.com/user

POST/PATCH 数据

{

"login": "superhin001",

"id": 21163682,

"node_id": "MDQ6VXNlcjIxMTYzNjgy",

"avatar_url": "https://avatars3.githubusercontent.com/u/21163682?v=4",

"gravatar_id": "",

"url": "https://api.github.com/users/superhin001",

"html_url": "https://github.com/superhin001",

"followers_url": "https://api.github.com/users/superhin001/followers",

"following_url": "https://api.github.com/users/superhin001/following{/other_user}",

"gists_url": "https://api.github.com/users/superhin001/gists{/gist_id}",

"starred_url": "https://api.github.com/users/superhin001/starred{/owner}{/repo}",

"subscriptions_url": "https://api.github.com/users/superhin001/subscriptions",

"organizations_url": "https://api.github.com/users/superhin001/orgs",

"repos_url": "https://api.github.com/users/superhin001/repos",

"events_url": "https://api.github.com/users/superhin001/events{/privacy}",

"received_events_url": "https://api.github.com/users/superhin001/received_events",

"type": "User",

"site_admin": false,

"name": "我是韩老师",

"company": null,

"blog": "",

"location": null,

"email": "superhin@126.com",

"hireable": null,

"bio": null,

"public_repos": 3,

"public_gists": 0,

"followers": 0,

"following": 0,

"created_at": "2016-08-22T01:12:32Z",

"updated_at": "2018-09-14T02:33:43Z",

"private_gists": 0,

"total_private_repos": 0,

"owned_private_repos": 0,

"disk_usage": 45430,

"collaborators": 0,

"two_factor_authentication": false,

"plan": {

"name": "free",

"space": 976562499,

"collaborators": 0,

"private_repos": 0

}

}

5dd299c23eb0

GET https://api.github.com/user/keys

5dd299c23eb0

POST https://api.github.com/user/keys

POST 数据

{

"id": 30742411,

"key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDfsTJs7mNWstJ+tO6O1jQHKdDdnldqlqkO0gAune9EH7oqICD1hP7c1duNZwvNnvyGa7SyqamIpNXmSYv303FEVAXzPsb9MzCChG16gzevQtbIX4Qt7vFOsHNSCikSCD/s6DMa0Koryiu7Yju5mW9UUnjVM+a1P80SOiK7p2UBQPFVKRrUtr0htV3U6a2rdP51Vzm2UCjChTUa4q7L3m4C7oB9aSvUsNTk+PmuJlAer4oOd7FsNPqD1Or3lRKAmgxbTX4xTaOkwibK0t2eYkh/VTUPMQ9wDwpa4hZLiEq9qSew3McCwsl70k4H0H4F/VwV2sSCXqZu274YmNDT5Hl3 hanzhichao@hanzhichao01",

"title": "test3",

"verified": true,

"created_at": "2018-09-14T09:54:51Z",

"read_only": false

}

Web Service

Web Service 是一种跨平台(Java对象,Python也可以调用)RPC(远程方法调用)解决方案。

基于SOAP协议,使用XML这种跨平台语言传输对远程方法的调用信息及返回结果,并提供WSDL接口描述服务

SOAP:简单面向对象协议, 基于XML语言,使用HTTP协议传输

XML: 可扩展标记语言,同JSON一样是一种跨平台语言

WSDL: Web Service服务描述语言,提供远程对象的调用描述信息(类似于接口文档,XML格式)

SOAP格式

SOAP协议基于XML语言, SOAP消息体首先必须有个信封(Enelope),信封中可以有信息头(Header)和信息体(Body),其中Body中还可以包含错误信息(Fault)

基本格式如下:

......

......

使用SoupUI

示例接口: http://115.28.108.130:4000/?wsdl

由于Postman等不具备将wsdl接口信息解析成对象描述的功能,我们使用另一个SOAP接口专用的测试工具SoupUI

新建项目

5dd299c23eb0

File -> 新建SOAP项目

5dd299c23eb0

填入项目名,WSDL地址,点击OK

5dd299c23eb0

保存后自动解析出所有方法(接口)信息

发送接口

5dd299c23eb0

填写参数处

5dd299c23eb0

填写完参数,点击发送按钮,查看响应结果

使用Fiddler抓包,查看raw格式:

POST http://115.28.108.130:4000/ HTTP/1.1

Accept-Encoding: gzip,deflate

Content-Type: text/xml;charset=UTF-8

SOAPAction: "addUser"

Content-Length: 370

Host: 115.28.108.130:4000

Connection: Keep-Alive

User-Agent: Apache-HttpClient/4.1.1 (java 1.5)

范冰冰

123456

使用Postman发送SOAP接口

5dd299c23eb0

Postman发送SOAP接口

text/xml 和 application/xml的区别: 当你<?xml version='1.0' encoding='UTF-8'>指定编码的时候,使用application/xml会安装xml指定的编码传输,而使用text/html会默认使用us-ascii编码编码传输数据

使用Python操作Web service接口

pip install suds-jurko

from suds.client import Client

service = Client("http://115.28.108.130:4000/?wsdl").service # 获取远端服务对象

result = service.addUser("范冰冰", "123456") # 向本地方法一样调用

print(result) # 输出 用户已存在

使用requests库发送

import requests

url = 'http://115.28.108.130:4000/'

data = '''

张三

123456

'''.encode('utf-8')

res = requests.post(url=url,data=data)

print(res.text)

结果:

<?xml version='1.0' encoding='UTF-8'?>

用户已存在

XML解析

XML: 可扩展标记语言,使用标签,多级树状结构,多用来存储和传输数据,如:

Everyday Italian

Giada De Laurentiis

2005

30.00

Harry Potter

J K. Rowling

2005

29.99

Learning XML

Erik T. Ray

2003

39.95

根元素(根节点),父元素,子元素,同级元素:bookstore为根元素,book是title的父元素,title是book的子元素,title和author是同级元素

标签,属性,文本:bookstore boot title等为标签(元素节点),boot中category="COOKING" category为属性,COOKING为属性值,

之间的Everyday Italian为文本

Python解析XML

加载元素树(ElementTree)得到根节点

从根节点使用xpath查找其他节点

from xml.etree import ElementTree

d = '''

Everyday Italian

Giada De Laurentiis

2005

30.00

Harry Potter

J K. Rowling

2005

29.99

Learning XML

Erik T. Ray

2003

39.95

'''

root = ElementTree.fromstring(d) # 加载元素树(ElementTree)得到根节点

print(root.find(".")) # 选择当前节点

print(root.find("book")) # 选择标签为book的子节点

print(root.find("book[2]")) # 选择标签为book的第三个子节点

print(root.find("book[@category='COOKING']")) # 选择标签为book切标签属性为category="COOKING"

print(root.find("./book/[title='Harry Potter']")) # 选择标签为book的节点中包含子标签title 切title的文本内容为Harry Potter

结果:

find()返回的是节点对象,可以通过.tag获取标签名,.attrib获取属性字典,.text获取文本

XPath选择器

路径: 按路径选择

标签名: 选定所有该名的标签

*: 选定所有元素

. : 选择当前节点

..: 选择上级节点

//: 选择当前元素下所有级别的元素

[@属性名]:选择所有具有当前属性的元素

[@属性名=属性值]: 选择属性=属性值的元素

[子标签名]:选择具有当前子标签的元素

[子标签名='文本']: 选择子标签文本的元素

常用的三种定位元素方法

从根节点按路径选择: root.find("./book[3]/title")

按属性并结合相对路径选择: root.find(book[@category='WEB']/title)

按所包含的独特子标签选择: root.find(book[title='Harry Potter']/title)

Mock Server

Mock 即模拟,就是在测试过程中,对于某些不容易构造或者不容易获取的对象,用一个虚拟的对象来创建以便测试的测试方法,其最大的优势就是降级前后端耦合度,使前端工程师可以不依赖后端返回数据,先开发前端样式以及逻辑处理

简单来说: Mock是用了解决依赖问题的,将复杂的/不稳定的/还未建立的依赖对象用一个简单的假对象来代替

Mock Server 即Mock接口服务器,可以通过配置快速Mock出新的接口

Mock Server的使用范围

前后端分离项目

所测接口依赖第三方系统(还未具备)

所测接口依赖复杂或依赖的接口不稳定,并不作为主要验证对象

同时在接口还未开发好时,提供Mock接口(假接口)会比只有接口文档更直观,并能有效减少沟通成本和一些文档理解bug

Postman的Mock Server功能

5dd299c23eb0

New -> Mock Server

5dd299c23eb0

添加接口及返回值

5dd299c23eb0

新建Mock环境

5dd299c23eb0

测试Mock接口

Postman还可以基于Collection建立Mock Server,这里不再详述

Python+Flask自己搭建Mock接口

使用Flask包我们可以快速搭建Mock接口

pip install flask

from flask import Flask, request, jsonify, abort

import random

app = Flask(__name__) # 实例化一个Flask对象

@app.route("/api/user/reg/", methods=["POST"])

def reg():

if not request.json or not 'name' in request.json or not 'password' in request.json:

abort(404)

res = [

{

"code": "100000",

"msg": "成功",

"data": {

"name": "李六",

"password": "e10adc3949ba59abbe56e057f20f883e"

}

},

{

"code": "100001",

"msg": "失败,用户已存在",

"data": {

"name": "李六",

"password": "e10adc3949ba59abbe56e057f20f883e"

}

},

{

"code": "100002",

"msg": "失败,添加用户失败",

"data": {

"name": "李六",

"password": "e10adc3949ba59abbe56e057f20f883e"

}

}

]

return jsonify(random.choice(res))

if __name__ == '__main__':

app.run()

5dd299c23eb0

使用Mock接口

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值