Python接口测试实战5(下) - RESTful、Web Service及Mock Serve
本节内容
REST及RESTful API
REST:表述性状态转移或表现层状态转移,“表现”及每个接口地址(URI)都表现为(视为)一个资源对象(文本资源、图片资源、服务资源),状态转移指通过POST/PUT方法发送完整的新状态信息来更改资源对象的状态
RESTful API是一种接口设计风格或规范,主要有以下特点:
示例: https://api.github.com GET https://api.github.com/user 获取用户信息
GET https://api.github.com/user
POST/PATCH https://api.github.com/user 修改用户信息
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": "[email?protected]","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,"private_repos": 0 } }
GET https://api.github.com/user/keys 获取用户所有SSH-Key信息
GET https://api.github.com/user/keys
POST https://api.github.com/user/keys 新建Key
POST https://api.github.com/user/keys
POST 数据 {
"id": 30742411,"key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDfsTJs7mNWstJ+tO6O1jQHKdDdnldqlqkO0gAune9EH7oqICD1hP7c1duNZwvNnvyGa7SyqamIpNXmSYv303FEVAXzPsb9MzCChG16gzevQtbIX4Qt7vFOsHNSCikSCD/s6DMa0Koryiu7Yju5mW9UUnjVM+a1P80SOiK7p2UBQPFVKRrUtr0htV3U6a2rdP51Vzm2UCjChTUa4q7L3m4C7oB9aSvUsNTk+PmuJlAer4oOd7FsNPqD1Or3lRKAmgxbTX4xTaOkwibK0t2eYkh/VTUPMQ9wDwpa4hZLiEq9qSew3McCwsl70k4H0H4F/VwV2sSCXqZu274YmNDT5Hl3 [email?protected]","title": "test3","verified": true,"created_at": "2018-09-14T09:54:51Z","read_only": false }
Web ServiceWeb Service 是一种跨平台(Java对象,Python也可以调用)RPC(远程方法调用)解决方案。
SOAP格式SOAP协议基于XML语言, SOAP消息体首先必须有个信封(Enelope),信封中可以有信息头(Header)和信息体(Body),其中Body中还可以包含错误信息(Fault) <!-- 信封固定格式 指定命名空间为soapenv --> <soapenv:Envelope xmlns:soapenv="http://www.w3.org/2001/12/soap-envelope" soapenv:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> <soapenv:Header> <!--信息头 可选,可写成但标签--> ...... </soapenv:Header> <soapenv:Body> <!--信息体 实际调用内容--> ...... </soapenv:Body> </soap:Envelope>
使用SoupUI
填入项目名,WSDL地址,点击OK
保存后自动解析出所有方法(接口)信息
填写参数处
填写完参数,点击发送按钮,查看响应结果
使用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)
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:user="UserService"> <soapenv:Header/> <soapenv:Body> <user:addUser> <!--Optional:--> <user:name>范冰冰</user:name> <!--Optional:--> <user:password>123456</user:password> </user:addUser> </soapenv:Body> </soapenv:Envelope>
使用Postman发送SOAP接口
Postman发送SOAP接口
使用Python操作Web service接口
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 = ‘‘‘<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:user="UserService"> <soapenv:Header/> <soapenv:Body> <user:addUser> <!--Optional:--> <user:name>张三</user:name> <!--Optional:--> <user:password>123456</user:password> </user:addUser> </soapenv:Body> </soapenv:Envelope> ‘‘‘.encode(‘utf-8‘) res = requests.post(url=url,data=data) print(res.text)
结果: <?xml version=‘1.0‘ encoding=‘UTF-8‘?> <soap11env:Envelope xmlns:soap11env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns="UserService"><soap11env:Body><tns:addUserResponse><tns:addUserResult>用户已存在</tns:addUserResult></tns:addUserResponse></soap11env:Body></soap11env:Envelope>
XML解析XML: 可扩展标记语言,使用<tag></tag>标签,多级树状结构,多用来存储和传输数据,如: <bookstore> <book category="COOKING"> <title lang="en">Everyday Italian</title> <author>Giada De Laurentiis</author> <year>2005</year> <price>30.00</price> </book> <book category="CHILDREN"> <title lang="en">Harry Potter</title> <author>J K. Rowling</author> <year>2005</year> <price>29.99</price> </book> <book category="WEB"> <title lang="en">Learning XML</title> <author>Erik T. Ray</author> <year>2003</year> <price>39.95</price> </book> </bookstore>
Python解析XML
from xml.etree import ElementTree
d = ‘‘‘<bookstore> <book category="COOKING"> <title lang="en">Everyday Italian</title> <author>Giada De Laurentiis</author> <year>2005</year> <price>30.00</price> </book> <book category="CHILDREN"> <title lang="en">Harry Potter</title> <author>J K. Rowling</author> <year>2005</year> <price>29.99</price> </book> <book category="WEB"> <title lang="en">Learning XML</title> <author>Erik T. Ray</author> <year>2003</year> <price>39.95</price> </book> </bookstore> ‘‘‘ 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
结果: <Element ‘bookstore‘ at 0x000002406B666688> <Element ‘book‘ at 0x000002406B6666D8> <Element ‘book‘ at 0x000002406B8600E8> <Element ‘book‘ at 0x000002406B6666D8> <Element ‘book‘ at 0x000002406B8600E8>
XPath选择器
常用的三种定位元素方法
Mock ServerMock 即模拟,就是在测试过程中,对于某些不容易构造或者不容易获取的对象,用一个虚拟的对象来创建以便测试的测试方法,其最大的优势就是降级前后端耦合度,使前端工程师可以不依赖后端返回数据,先开发前端样式以及逻辑处理 Mock Server 即Mock接口服务器,可以通过配置快速Mock出新的接口
同时在接口还未开发好时,提供Mock接口(假接口)会比只有接口文档更直观,并能有效减少沟通成本和一些文档理解bug Postman的Mock Server功能
New -> Mock Server
添加接口及返回值
新建Mock环境
测试Mock接口
Python+Flask自己搭建Mock接口
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": "失败,用户已存在",{ "code": "100002","msg": "失败,添加用户失败","password": "e10adc3949ba59abbe56e057f20f883e" } } ] return jsonify(random.choice(res)) if __name__ == ‘__main__‘: app.run()
使用Mock接口
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |