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

news2024/12/27 1:13:16

本节内容

  • 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

GET https://api.github.com/user 获取用户信息

POST/PATCH https://api.github.com/user 修改用户信息

POST/PATCH 数据

Copy{"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}}

GET https://api.github.com/user/keys 获取用户所有SSH-Key信息

POST https://api.github.com/user/keys 新建Key

POST 数据

Copy{"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)

基本格式如下:

Copy<!-- 信封固定格式 指定命名空间为soapenv --><soapenv:Envelopexmlns: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>
SOAP详细教程: http://www.runoob.com/soap/soap-header.html

使用SoupUI

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

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

SoupUI下载地址: http://www.wmzhe.com/soft-32815.html

1.新建项目

2.发送接口

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

CopyPOSThttp://115.28.108.130:4000/ HTTP/1.1Accept-Encoding: gzip,deflate
Content-Type: text/xml;charset=UTF-8SOAPAction: "addUser"Content-Length: 370Host: 115.28.108.130:4000Connection: Keep-AliveUser-Agent: Apache-HttpClient/4.1.1 (java 1.5)

<soapenv:Envelopexmlns: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接口

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
Copyfrom suds.client import Client

service = Client("http://115.28.108.130:4000/?wsdl").service  # 获取远端服务对象
result = service.addUser("范冰冰", "123456")  # 向本地方法一样调用print(result)  # 输出 用户已存在

使用requests库发送

Copyimport requests

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

data = '''<soapenv:Envelopexmlns: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)

结果:

Copy<?xml version='1.0' encoding='UTF-8'?><soap11env:Envelopexmlns: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: 可扩展标记语言,使用标签,多级树状结构,多用来存储和传输数据,如:

Copy<bookstore>
	<bookcategory="COOKING">
		<titlelang="en">Everyday Italian</title>
		<author>Giada De Laurentiis</author>
		<year>2005</year>
		<price>30.00</price>
	</book>
	<bookcategory="CHILDREN">
		<titlelang="en">Harry Potter</title>
		<author>J K. Rowling</author>
		<year>2005</year>
		<price>29.99</price>
	</book>
	<bookcategory="WEB">
		<titlelang="en">Learning XML</title>
		<author>Erik T. Ray</author>
		<year>2003</year>
		<price>39.95</price>
	</book></bookstore>
  • 根元素(根节点),父元素,子元素,同级元素:bookstore为根元素,book是title的父元素,title是book的子元素,title和author是同级元素

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

Python解析XML

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

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

Copyfrom xml.etree import ElementTree
d = '''<bookstore>
	<bookcategory="COOKING">
		<titlelang="en">Everyday Italian</title>
		<author>Giada De Laurentiis</author>
		<year>2005</year>
		<price>30.00</price>
	</book>
	<bookcategory="CHILDREN">
		<titlelang="en">Harry Potter</title>
		<author>J K. Rowling</author>
		<year>2005</year>
		<price>29.99</price>
	</book>
	<bookcategory="WEB">
		<titlelang="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

结果:

Copy<Element'bookstore' at 0x000002406B666688>
<Element'book' at 0x000002406B6666D8>
<Element'book' at 0x000002406B8600E8>
<Element'book' at 0x000002406B6666D8>
<Element'book' at 0x000002406B8600E8>
find()返回的是节点对象,可以通过.tag获取标签名,.attrib获取属性字典,.text获取文本

XPath选择器

  • 路径: 按路径选择

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

  • *: 选定所有元素

  • . : 选择当前节点

  • ..: 选择上级节点

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

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

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

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

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

常用的三种定位元素方法

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

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

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

Mock Server

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

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

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

Mock Server的使用范围

  • 前后端分离项目

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

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

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

Postman的Mock Server功能

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

Python+Flask自己搭建Mock接口

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

pip install flask
Copyfrom flask import Flask, request, jsonify, abort
import random

app = Flask(__name__) # 实例化一个Flask对象@app.route("/api/user/reg/", methods=["POST"])defreg():
    ifnot request.json ornot'name'in request.json ornot'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()
高效学习,快速掌握Python自动化所有领域技能
同步快速解决各种问题
配套实战项目练习

如有不懂还要咨询下方小卡片,博主也希望和志同道合的测试人员一起学习进步

在适当的年龄,选择适当的岗位,尽量去发挥好自己的优势。

我的自动化测试开发之路,一路走来都离不每个阶段的计划,因为自己喜欢规划和总结,

测试开发视频教程、学习笔记领取传送门!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/192890.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

请问软件设计师、网络工程师、软件评测师还是系统集成项目管理师,哪个好考?

软件设计师、网络工程师、软件评测师还是系统集成项目管理师&#xff1f;这些都是属于软考中级科目&#xff0c;看自己是想从事哪个方向咯。都可以备考啊&#xff0c;毕竟含金量都差不多的&#xff01; 因为自己备考的是网工&#xff0c;就说说网工的备考如何吧 一、中级网络…

Quest Pro降价和Vive XR Elite之我见

本来没打算写Vive XR Elite&#xff0c;作为HTC首个支持VST透视的VR头显&#xff0c;它也引起了业内关注&#xff0c;尤其是去年10月份Meta Quest Pro重磅发布之后&#xff0c;大家就会看到&#xff0c;领域内的玩家都在朝着VST发力。那为什么现在来写Vive XR Elite呢&#xff…

即时通讯开发之TCP/IP中的TCP 协议概述

终于看到了 TCP 协议,这是 TCP/IP 详解里面最重要也是最精彩的部分,要花大力气来读。前面的 TFTP 和 BOOTP 都是一些简单的协议,就不写笔记了,写起来也没啥东西。 TCP 和 UDP 处在同一层---运输层,但是 TCP 和 UDP 最不同的地方是,TCP 提供了一种可靠的数据传输服务,TCP 是面向…

从零开始手写基于Web Components组件

前言 本文将详细讲解如何用最基本的typescript&#xff0c;vite&#xff0c;less构建基于Web Components的组件&#xff0c;目前已实现Button&#xff0c;Icon&#xff0c;Image&#xff0c;Tabs&#xff0c;Input&#xff0c;Message组件。首先介绍项目的整体架构&#xff0c…

新C++(6):继承那些事儿

"你在酒杯还未干的时间里&#xff0c;收藏这份情谊"一、回顾继承什么是继承&#xff1f;继承是面向对象编程语言的三大特征之一。通过继承机制&#xff0c;面向对象的程序设计可以很大限度地对代码进行复用。它允许程序员在保持原有类特性的基础上进行扩展&#xff0…

scrapy_redis概念作用和流程

scrapy_redis概念作用和流程 学习目标 了解 分布式的概念及特点了解 scarpy_redis的概念了解 scrapy_redis的作用了解 scrapy_redis的工作流程 在前面scrapy框架中我们已经能够使用框架实现爬虫爬取网站数据,如果当前网站的数据比较庞大, 我们就需要使用分布式来更快的爬取数…

制药行业中各种化合物的净化,大孔吸附净化氨基酸

基于吸附功能的聚苯乙烯特种树脂 Tulsimer ADS-600 是一款没有离子官能基的&#xff0c;由交联聚苯乙烯合成的功能强大的吸附型树脂。 Tulsimer ADS-600 主要应用于水溶液中吸附酚及其化合物&#xff0c;氯代烃等含氯物质&#xff0c;表面活性剂&#xff0c;氨基酸&#…

【C++修炼之路】C++入门(中)—— 函数重载和引用

&#x1f451;作者主页&#xff1a;安 度 因 &#x1f3e0;学习社区&#xff1a;StackFrame &#x1f4d6;专栏链接&#xff1a;C修炼之路 文章目录一、前言二、函数重载1、重载规则2、函数名修饰规则三、引用1、区分2、本质3、特性4、应用a、做参数b、做返回值5、效率比较6、常…

windows安装cnpm

文章目录1 cnpm简介2 cnpm 安装步骤1 cnpm简介 npm下载速度比较慢&#xff0c;可以通过cnpm下载node包 2 cnpm 安装步骤 找到nodejs的安装路径&#xff1a; 使用nvm安装和管理node 直接安装node的方式 直接通过安装包安装node的方式&#xff0c;node会被安装在某个实际目录下…

docker pull nginx

取最新版的 Nginx 镜像 docker pull nginx:latest 查看本地镜像 使用以下命令来查看是否已安装了 nginx&#xff1a; $ docker images 运行容器 安装完成后&#xff0c;我们可以使用以下命令来运行 nginx 容器&#xff1a; $ docker run --name nginx-door -p 8080:80 -…

VS code的使用指南

VS code的使用指南 VS code的安装与下载 VS Code的安装地址的 在下面选择版本的位置进行安装&#xff08;一般选择Stable进行安装&#xff0c;这个软件是跨系统的安装与设置相关的内容信息&#xff09;。 插件安装 直接点击这个位置,选择自己需要的相应的插件 这些都是常用的…

软件工程(四)——结构化设计、模块独立性、面向对象设计、软件测试与维护

目录 一、界面设计 二、结构化设计 1.概要设计 2模块独立性 三、面向对象设计 1.面向对象设计的五大基本原则(SOLID)和其他5个原则 2.设计模式 三、软件测试与维护 1.白盒测试和黑盒测试 2.测试的阶段 3.软件维护阶段 四、系统演化策略 一、界面设计 人机界面设计&…

50条必背JAVA知识点(一)

1.编写&#xff1a;编写的Java代码保存在以“.java”结尾的源文件中。 2.编译&#xff1a;使用javac.exe命令编译java源文件&#xff0c;生成字节码文件。格式&#xff1a;javac 源文件名.java 3.运行&#xff1a;使用java.exe命令解释运行字节码文件。格式&#xff1a;java …

深入浅出PyTorch-PyTorch的主要组成模块

目录1.基本配置2.数据读入3.模型构建3.1神经网络的构造3.2神经网络中常见的层常见网络层的构造常见的网络层3.3模型示例卷积神经网络&#xff08;LeNet&#xff09;深度卷积神经网络&#xff08;AlexNet&#xff09;4.模型初始化5.损失函数6.训练和评估深度学习和机器学习在流程…

python小游戏——塔防小游戏代码开源

♥️作者&#xff1a;小刘在这里 ♥️每天分享云计算网络运维课堂笔记&#xff0c;努力不一定有收获&#xff0c;但一定会有收获加油&#xff01;一起努力&#xff0c;共赴美好人生&#xff01; ♥️夕阳下&#xff0c;是最美的&#xff0c;绽放&#xff0c;愿所有的美好&#…

TCP/IP网络编程——优雅的断开套接字的连接

完整版文章请参考&#xff1a; TCP/IP网络编程完整版文章 文章目录第 7 章 优雅的断开套接字的连接7.1 基于 TCP 的半关闭7.1.1 单方面断开连接带来的问题7.1.2 套接字和流&#xff08;Stream&#xff09;7.1.3 针对优雅断开的 shutdown 函数7.1.4 为何要半关闭7.1.5 基于半关闭…

AST入门与反混淆初体验

文章目录1.什么是AST&#xff1f;2. AST反混淆的目的3. babel库安装4. 直观的理解AST5.如何用AST解混淆&#xff1f;思路是什么&#xff1f;6. babel库的学习7. AST反混淆初体验-常量折叠1.什么是AST&#xff1f; ​ 在计算机科学中&#xff0c;抽象语法树&#xff08;Abstrac…

【服务器数据恢复】raid5中3块磁盘先后掉线的数据恢复案例

服务器数据恢复环境&故障&#xff1a; 某单位同友存储设备&#xff0c;该存储有大于5台的虚拟机&#xff0c;其中有3台linux系统虚拟机存储重要数据。存储设备中组建的raid5由于未知原因崩溃导致存储无法启动。 存储结构&#xff1a; 服务器数据恢复过程&#xff1a; 1、对…

C语言进阶——字符函数和字符串函数(上)

目录 一、前言 二、正文 1.求字符串长度 ♥strlen 2.长度不受限制的字符串函数 ♥strcpy ♥strcat ♥strcmp 三、结语 一、前言 一日不见&#xff0c;如隔三秋&#xff1b;几日不见&#xff0c;甚是想念。猜想小伙伴们在平常进行有关字符的练习时遇到有关字符的操作却无从下手…

GEC6818 移植 rtl8723bu wifi驱动

文章目录1. 配置内核2、RTL8723BU 模块驱动编译2.1 下载解压2.2 配置编译3. openssl 移植3.1 下载解压3.2 配置3.3 编译安装4. libnl 移植4.1 下载解压4.2 进入源码目录并配置4.3 编译安装5. wpa_supplicant 移植5.1 解压源码5.2 配置5.3 make编译6. 启动wifi网卡6.1 配置WiFi连…