一、接口测试基础知识
定义和概念
- 定义:接口通常代指API,它是软件组件之间通信的方式。API定义了如何通过特定的协议(如HTTP)来调用服务或功能,以及如何发送请求和接受响应。接口测试对于保证软件质量至关重要,因为它验证了组件之间的交互是否符合预期,包括验证数据的有效性、处理异常情况的能力、性能表现、安全等方面。
- 通常接触到的接口分为以下几种:
(1)系统内部服务层级之间的接口调用
这类接口通常发生在单个应用程序或服务内部,业务逻辑层调用数据访问层的接口来存取数据库中的数据,比如后端服务应用层调用service层接口,service层调用DAO层的接口,这个地方的接口测试属于白盒范畴,一般开发自己做。
(2)服务之间的接口调用
这类接口涉及到同一系统内部的不同服务之间的交互,应用于微服务中。
微服务之间的调用:不同的微服务通过APi调用来相互协助,共同完成一个业务流程
服务网关与服务:服务网关作为入口点,处理外部请求并将请求转发到后端服务
(3)系统之间的接口调用
这类接口涉及不同系统之间的交互,通常跨越不同的组织边界。这些接口可以包括:
第三方服务调用:应用程序调用第三方提供商的服务,例如支付网关、地图服务等。
合作伙伴系统调用:两个或多个组织之间通过API进行数据交换,例如供应链管理系统之间的订单处理。 - 怎么开展接口测试
流程如下:
(1)需求确定后,开发出API文档
(2)拿到开发文档,编写接口测试用例
(3)开发交付
(4)实施接口测试
TCP/IP、HTTP协议
- TCP/IP协议
是一组用于互联网通信的协议标准,它定义了数据在网络中的传输方式。TCP/IP协议由多个层次组成,每个层次负责不同的功能。
(1)应用层
应用层协议定义了应用程序如何使用网络进行通信。常见的应用层协议包括: - HTTP:用于web应用的协议,定义了客户端和服务器之间的通信方式,用于传输
- FTP:用于文件传输的协议
- SMTP:用于电子邮件传输的协议
- DNS:用于域名解析的协议
- Telnet:用于远程登陆的协议
- SSH:用于安全远程登陆的协议
作用:处理网络应用程序与网络之间的交互,支持用户直接使用的各种应用协议。
(2)传输层
传输层协议负责端到端的数据传输,并保证数据的完整性。主要协议包括: - TCP:提供面向连接的、可靠的字节流服务。TCP通过三次握手建立连接,并使用序列号和确认机制来确保数据的可靠传输。
- UDP:提供无连接的,不可靠的数据服务。UDP不保证数据的顺序和完整性,但提供了更快的数据传输速度。
作用:为应用程序提供数据传输服务,包括数据的分段和重组。
(3)网络层
网络层协议负责数据包的寻址和路由。主要协议包括: - IP:为数据包分配IP地址,并负责数据包在网络中的传输。IPv4是当前最广泛使用的版本,IPv6是下一个版本,提供了更大的地址空间。
- ICMP:用于发送错误消息和操作信息,常用诊断(如ping命令)。
作用:确保数据包能够从源传送到目标主机,通过路由转发和处理。
(4)链路层
链路层协议负责在相邻节点之间传输数据帧。主要协议包括: - Ethernet:局域网中最常见的物理层协议
- Wi-Fi:无线局域网协议
- PPP:用于串行的数据链路层协议
作用:负责将数据传输到网络中的另一个主机,处理硬件地址和数据链路协议。
HTTP协议
HTP(超文本传输协议)是用于在web上传输数据的协议,是互联网上应用最为广泛的一种网络传输协议。它定义了客户端(如浏览器)与服务器之间的通信规范,以实现对各种资源(如HTML页面、图像、音频、视频等)的传输和访问。
- 特点
无连接:HTTP协议不需要在客户端和服务器之间建立持久的连接,每次请求完成后连接即被关闭,减少了网络开销。
无状态:HTTP协议对事务的处理没有记忆能力,每次请求都需要提供完整的请求信息。
面向对象:HTTP协议可以传输任何类型的数据对象。
无阻塞:HTTP协议不会限制客户端的请求数量和大小,使得服务器可以处理大量的请求。
可缓存:HTTP协议允许客户端缓存服务器响应的内容,以提高响应速度和减少网络流量。 - 工作原理
HTTP协议是基于TCP实现的请求-响应协议,其工作过程主要分为以下几个步骤:
三次握手:建立TCP连接。
客户端发送请求:使用HTTP请求报文向服务器请求资源。
服务器发送响应:服务器处理请求后,使用HTTP响应报文将资源返回给客户端。
四次挥手:关闭TCP连接。 - HTTP报文结构
HTTP报文分为请求报文和响应报文两种类型:
请求报文:
请求行:包含请求方法(如GET、POST)、请求URL和HTTP协议版本。
请求头:包含请求的客户端信息,如客户端类型、支持的内容格式、是否支持压缩等。
请求体(可选):包含请求的数据部分,如POST请求中的表单数据。
响应报文:
状态行:包含HTTP协议版本、响应状态码和状态信息。
响应头:包含响应的服务器资源信息,如内容类型、内容编码、长度和连接方式等。
响应空行:用来间隔/区分响应头和响应体。
响应体:服务器响应的内容,通常是一个HTML页面的代码或者给客户端的数据。 - 常见方法
HTTP协议中共定义了八种请求方法,用于表明对指定资源的不同操作方式,包括OPTIONS、GET、HEAD、POST、PUT、DELETE、TRACE和CONNECT。其中,GET和POST是最常用的两种请求方法:
GET:主要用于请求数据,请求参数拼接在URL后面。
POST:主要用于传递数据,常用于表单提交或上传文件,请求参数放在请求体里面。 - 状态码
HTTP协议定义了多种状态码,用于表示服务器对请求的响应状态。常见的状态码包括:
200 OK:请求成功。
301 Moved Permanently:资源被永久转移到其他URL。
400 Bad Request:语法错误,服务器无法理解请求。
404 Not Found:请求的资源不存在。
500 Internal Server Error:服务器内部错误,无法完成请求。 - HTTPS
TLS/SSL加密:HTTPS(HTTP Secure)通过加密确保数据的机密性和完整性。
证书:通过数字证书验证服务器的身份,防止中间人攻击。
request库
request库,是一个非常强大且易于使用的HTTP库,它允许我们发送HTTP请求,与web服务进行交互。支持多种 HTTP 方法,包括 GET、POST、PUT、DELETE 等,并且可以处理 cookies、重定向、认证等高级功能。
- 基本概念
GET:从服务器获取资源
POST:向服务器提交数据,通常用于创建新资源
PUT:更新服务器上的资源
DELETE:删除服务器的资源
URL(Uniform Resource Locator):用于定位资源的字符串,如https://api.example.com/data。
请求头(Headers):包含了关于请求的元数据,如内容类型、用户代理等。
请求体(Body):通常用于POST和PUT请求,包含要发送的数据。 - 基本使用
(1)发送GET请求
import requests
response = requests.get('http://httpbin.org/get')
print(response.text)
方法详解
requests.get(url, params=None, **kwargs):
参数:
url:要请求的url
params:附加到url查询字符串中的参数
kwargs:其他可选关键字参数,用于配置请求
可选关键字参数:
header(dict):请求头部,默认为none,表示不设置头部
timeout:设置请求超时时间
auth:认证信息,如果提供,则使用HTTP Basic Auth
Cookies:发送给服务器,默认为none
返回值:返回一个request.Response对象,该对象包含服务器的响应信息
异常处理:在使用get方法时,可能会遇到各种异常,如网络错误、超时等,可以通过捕获异常来处理这些问题。
(1)requests.exceptions.Timeout:用于处理请求超时的情况
(2)requests.exceptions.ConnectionError:用于处理与网络连接相关的问题,当无法建立到服务器的连接时抛出异常
(3)requests.exceptions.HTTPError:这个异常会在 HTTP 请求返回的状态码不在 200 到 300 之间的成功范围内时触发
(2)发送post请求
import requests
payload = {'key1':'value1', 'key2':'value2'}
response = requests.post('http://httpbin.org/post',data=payload)
print(response.text)
方法详解
requests.post(url, data=None, json=None, **kwargs)
参数说明:
url:要请求的url
data:发送到服务器的数据
如果是字典或列表元组,则会被转换成application/x-www-form-urlencode编码格式
如果是二进制字符串,则直接发送
如果是文件对象,则使用multipart/form-data编码
默认为none
json:发送到服务器的json数据,如果提供将会使用application/json发送
kwargs:其他可选关键字参数,用于配置请求
header:请求头部
timeout:设置请求超时时间
cookies:发送给服务器的cookie
files(dict):要上传的文件,字典的键是表单名称,值是文件对象
params:附加到url查询字符串中的参数
返回值:返回一个 requests.Response 对象,该对象包含服务器的响应信息
(3)响应内容解析
requests库在发送HTTP请求后会返回一个Response对象,该对象包含了服务器的响应以及相关的元数据。
# 检查响应状态码
response.status_code()
# 获取响应文本内容
response.text
# 获取响应头
response.headers
# 解析JSON格式的响应数据
response.json()
# 获取响应的原始数据(二进制),这对于处理图像、音频文件等非文本数据非常有用
response.content
session、Cookie、token
session与cookie、token
相同性
都为解决协议的无状态性
不同性
cookie存在客户端浏览器中
session存在服务器上
cookie
注意:当你手动点击退出登陆,你所加载这这些cookie就失效了。如果还需要通过cookie实现免登录,就要重新获取cookie信息。
session
是通过cookie发送的,使用cookie作为传输媒介
服务器向客户端浏览器发送一个名为 JSESSIONID 的 Cookie,它的值为该 Session 的 ID。
token
当用户第一次请求时,发送用户信息至服务器。服务器端对用户信息使用hs256算法及秘钥进行签名,并将这个签名和数据一起返回给客户端
服务端不保存token,token保存在客户端中
当客户端再次发送请求时,在请求信息中将token一起发送给服务端
服务器用同样的算法和秘钥对数据再进行一次签名,和token中的签名进行比较
token原理:
jwt规范
JSON web token是一种开发标准,它定义了一种紧凑和安全的标准,用于将各方之间的信息传输 为JSON
组成部分
头部:用于描述关于jwt的最基本的信息
负载
签名
cookie
Cookie是一种小型数据文件,由服务器生成并发送给客户端浏览器,浏览器在后续的请求中会自动带上这些Cookie发送给服务器。
Cookie 主要有以下几个特点:
键值对形式:每个 Cookie 都包含一个名称(键)和一个值。
过期时间:Cookie 可以设置一个过期时间,超过这个时间后,Cookie 将不再有效。
路径限制:Cookie 只能在指定的路径下使用。
域名限制:Cookie 只能发送回设置它的域名。
requests库中Cookie的管理是通过内置的session对象和cookies属性来实现的。Cookie 在 Web 开发中用于存储客户端的状态信息,如会话状态、用户偏好等。
requests的cookie管理
| # 设置Cookie
| # 客户端:1.验证码请求 2.登录请求
| # 服务端:1.生成Cookie 2.验证Cookie
| # data = {
| # "userName": "teacher",
| # "password": "BwzS/bebMJFwLEEXSr5AEIodWMlwUxmYvTeNAcE3TF9m7lbJVq621mLO+eDUGZbnD15ttZk6SZlgAiF8nayzrO/lL4vQeY0n6IQf5GlMOjxCWffYIEPvbZQSD8L9LqWXJkF790vDqSzxRT8EmdSi6ghvDSSEL1fFOL5kALhy7zg=",
| # "remember": False
| # }
| # response = requests.post(url='https://www.mindskip.net:7002/api/user/login', json = data)
| cookie = {'SESSION': 'ZGVmNDU3YmItNTJmZC00ZTE0LWFmNjctMDRmYzUzZWVlMWI0'}
| # print(cookie)
| data = {
| "userName": "",
| "classes": "null",
| "pageIndex": 1,
| "pageSize": 10
| }
| response = requests.post(url='https://www.mindskip.net:7002/api/teacher/classes/page/classesUser', json=data, cookies=cookie)
| if response.status_code == 200:
| print(response.json())
| else:
| print("请求失败")
|
1.创建session对象
session对象是requests库中用于管理会话状态的核心对象,它能够自动处理 Cookie 的发送和接收。
2.设置Cookie
可以手动设置一个Cookie,或者通过发送请求时从服务器获取Cookie
如果有正确的Cookie信息,通常可以跳过登录步骤直接访问需要认证的资源
3.使用session发送请求
| # 创建一个session对象
| session = requests.session()
| data = {
| "userName": "teacher",
| "password": "BwzS/bebMJFwLEEXSr5AEIodWMlwUxmYvTeNAcE3TF9m7lbJVq621mLO+eDUGZbnD15ttZk6SZlgAiF8nayzrO/lL4vQeY0n6IQf5GlMOjxCWffYIEPvbZQSD8L9LqWXJkF790vDqSzxRT8EmdSi6ghvDSSEL1fFOL5kALhy7zg=",
| "remember": False
| }
| # 发送请求
| response = session.post(url='https://www.mindskip.net:7002/api/user/login', json=data)
| data = {
| "userName": "",
| "classes": "null",
| "pageIndex": 1,
| "pageSize": 10
| }
| response = session.post(url='https://www.mindskip.net:7002/api/teacher/classes/page/classesUser', json=data)
| if response.status_code == 200:
| print(response.json())
| else:
| print("请求失败")
|
当使用session发送请求时,它会自动带上所有相关的Cookie