电商运营发展前景怎么样,南宁网站推广优化,北京建筑工程公司大全,网站前端设计招聘目录#xff1a;
接口自动化测试框架介绍 接口测试场景自动化测试场景接口测试在分层测试中的位置接口自动化测试与 Web/App 自动化测试对比接口自动化测试与 Web/App 自动化测试对比接口测试工具类型为什么推荐 RequestsRequests 优势Requests 环境准备接口请求方法接口请求…目录
接口自动化测试框架介绍 接口测试场景自动化测试场景接口测试在分层测试中的位置接口自动化测试与 Web/App 自动化测试对比接口自动化测试与 Web/App 自动化测试对比接口测试工具类型为什么推荐 RequestsRequests 优势Requests 环境准备接口请求方法接口请求参数接口请求头接口请求体-json接口响应断言json响应体断言宠物商店接口自动化测试实战
1.接口自动化测试框架介绍
接口测试场景 自动化测试场景 接口测试在分层测试中的位置 接口自动化测试与 Web/App 自动化测试对比 接口自动化测试与 Web/App 自动化测试对比
看起来接口自动化测试什么都比 Web/App 自动化测试要好为什么还要做 Web/App 自动化测试
接口关注数据无法触达用户体验。
接口测试工具类型
测试类型工具价值接口抓包Charles、Postman接口抓包工具可以抓取 App 的数据包接口测试Postman接口调试工具接口手工测试工具学习成本低直接安装即可使用接口自动化测试Requests、RestAssured用于接口自动化测试的 Java、Python 第三方库需要与对应编程语言结合使用性能测试JMeter性能测试工具
为什么推荐 Requests
是由 Python 实现的 API 测试框架。支持发起 POST, GET, PUT, DELETE 等请求。可以用来验证和校对响应信息。
Requests 优势
功能全面HTTP/HTTPS 支持全面。使用简单简单易用不用关心底层细节。定制性高结合测试框架完成二次封装比如 HttpRunner。
Requests 环境准备
安装命令pip install requests
2.接口请求方法
常见 HTTP 请求方法构造
方法说明requests.request()构造一个请求支撑以下各方法的基础方法。requests.get()构造 HTTP 协议中的 GET 请求。requests.post()构造 HTTP 协议中的 POST 请求。requests.put()构造 HTTP 协议中的 PUT 请求。requests.delete()构造 HTTP 协议中的 DELETE 请求。
底层设计 HTTP 协议知识回顾
URL 结构HTTP 请求HTTP 响应
构造 GET 请求
requests.get(url, paramsNone, **kwargs) url: 接口 url。params拼接在 url 中的请求参数。**kwargs更多底层支持的参数。
import requestsdef test_get():# 定义接口的 url 和拼接在 url 中的请求参数url https://httpbin.ceshiren.com/get# 发出 GET 请求r 接收接口响应r requests.get(url, verifyFalse)# 打印接口响应print(r.json())
构造 POST 请求
requests.post(url, dataNone, jsonNone, **kwargs) url: 接口 url。data表单格式请求体。jsonJSON 格式请求体。**kwargs更多底层支持的参数。
def test_post():# 定义接口的 urlurl https://httpbin.ceshiren.com/post# 发出 POST 请求r 接收接口响应response requests.post(url, verifyFalse)# 打印接口响应print(response.text)
构造 PUT 请求
requests.put(url, dataNone, **kwargs) url: 接口 url。data表单格式请求体。**kwargs更多底层支持的参数。
def test_put():# 定义接口的 urlurl https://httpbin.ceshiren.com/put# 发出 POST 请求r 接收接口响应r requests.put(url, verifyFalse)# 打印接口响应print(r) 构造 DELETE 请求
requests.delete(url, **kwargs) url: 接口 url。**kwargs更多底层支持的参数。
def test_delete():# 定义接口的 url 和表单格式请求体url https://httpbin.ceshiren.com/delete# 发出 POST 请求r 接收接口响应r requests.delete(url, verifyFalse)# 打印接口响应print(r)
构造请求方法
requests.request(method, url, **kwargs) method: 请求方法。 GETOPTIONSHEADPOSTPUTPATCHDELETE。url: 接口 url。**kwargs更多底层支持的参数。
GETGET是最常见的方法通常用于请求服务器发送某些资源。浏览器大部分时间都在使用GET方法比如当你在网址栏输入一个URL或者点击一个链接时。GET请求会将请求参数附加在URL后面以?符号分隔。这些参数会被浏览器发送到服务器但是浏览器不会保存这些参数也就是说GET请求不应该是用来发送敏感数据的因为这些数据可能会被第三方获取。OPTIONSOPTIONS方法用于获取目标资源支持的通信选项。它可以用来检查服务器的性能或者查看可以使用哪些HTTP方法来请求一个特定的URL。HEADHEAD方法和GET方法类似但是服务器在响应中只返回HTTP头部而不返回实际的数据。这可以用来检查链接的有效性或者获取有关资源的元数据例如Last-Modified头ETag头等。POSTPOST方法用于向服务器发送数据。它通常用于提交表单上传文件等。POST请求会将请求主体发送到服务器这个主体可以包含表单数据文件内容等。服务器可以根据这些数据执行一些动作例如创建新的资源。PUTPUT方法用于更新服务器上的资源。它与POST方法的主要区别是PUT请求通常知道它正在更新的资源的完整URL而POST请求通常不知道。因此PUT请求通常用于更新已经存在的资源而POST请求用于创建新的资源。PATCHPATCH方法是PUT方法的简化版本。与PUT相比PATCH请求通常只包含资源的部分更新信息而不是完整的信息。因此PATCH方法通常用于对资源的部分进行修改。DELETEDELETE方法是HTTP方法中最简单的一个。它用于从服务器删除资源。当你点击一个删除链接或者执行相应的JavaScript代码时你的浏览器就会向服务器发送一个DELETE请求。
def request(method, url, **kwargs):Constructs and sends a :class:Request Request.:param method: method for the new :class:Request object: GET, OPTIONS, HEAD, POST, PUT, PATCH, or DELETE.:param url: URL for the new :class:Request object.:param params: (optional) Dictionary, list of tuples or bytes to sendin the query string for the :class:Request.:param data: (optional) Dictionary, list of tuples, bytes, or file-likeobject to send in the body of the :class:Request.:param json: (optional) A JSON serializable Python object to send in the body of the :class:Request.:param headers: (optional) Dictionary of HTTP Headers to send with the :class:Request.:param cookies: (optional) Dict or CookieJar object to send with the :class:Request.:param files: (optional) Dictionary of name: file-like-objects (or {name: file-tuple}) for multipart encoding upload.file-tuple can be a 2-tuple (filename, fileobj), 3-tuple (filename, fileobj, content_type)or a 4-tuple (filename, fileobj, content_type, custom_headers), where content-type is a stringdefining the content type of the given file and custom_headers a dict-like object containing additional headersto add for the file.:param auth: (optional) Auth tuple to enable Basic/Digest/Custom HTTP Auth.:param timeout: (optional) How many seconds to wait for the server to send databefore giving up, as a float, or a :ref:(connect timeout, readtimeout) timeouts tuple.:type timeout: float or tuple:param allow_redirects: (optional) Boolean. Enable/disable GET/OPTIONS/POST/PUT/PATCH/DELETE/HEAD redirection. Defaults to True.:type allow_redirects: bool:param proxies: (optional) Dictionary mapping protocol to the URL of the proxy.:param verify: (optional) Either a boolean, in which case it controls whether we verifythe servers TLS certificate, or a string, in which case it must be a pathto a CA bundle to use. Defaults to True.:param stream: (optional) if False, the response content will be immediately downloaded.:param cert: (optional) if String, path to ssl client cert file (.pem). If Tuple, (cert, key) pair.:return: :class:Response Response object:rtype: requests.Response
底层参数说明
参数应用场景method请求方法url请求 URLparams请求中携带 URL 参数data请求中携带请求体默认为表单请求json请求中携带 json 格式的请求体headers请求中携带头信息cookies请求中携带 cookiesfiles请求中携带文件格式的请求体auth请求中携带认证信息timeout设置请求超时时间allow_redirects请求是否允许重定向proxies设置请求代理verify请求是否要认证cert请求中携带 ssl 证书 3.接口请求参数
请求参数简介
接口请求中携带的会在路径之后使用?代表客户端向服务端传递的参数。使用 keyvalue 形式拼接在 URL 中。如果有多个则使用分隔案例 https://ceshiren.com/search?expandedtrueqrequests 携带请求参数的方式
常用两种方式 直接在 URL 中拼接?usernameLiMingid666。通过 params 参数传递requests.get(url, params) 携带请求参数的 GET 请求
def test_get_by_params():url https://httpbin.ceshiren.com/getparams {get_key: get_value}r requests.get(url, paramsparams, verifyFalse)print(r.json())def test_get_by_url():url https://httpbin.ceshiren.com/get?get_keyget_valuer requests.get(url, verifyFalse)print(r.json())
携带请求参数的 POST 请求
def test_post_by_params():url https://httpbin.ceshiren.com/postparams {post_key: post_value}r requests.post(url, paramsparams,verifyFalse)print(r.json())
4.接口请求头
请求头信息的使用场景
身份认证指定数据类型 请求头信息
HTTP 请求头是在 HTTP 请求消息中包含的元数据信息用于描述请求或响应的一些属性和特征。实际工作过程中具体要关注的头信息字段需要和研发沟通。常见的头信息右侧表格:
内容含义Authorization表示客户端请求的身份验证信息Cookie表示客户端的状态信息通常用于身份验证和会话管理Content-Type表示请求消息体的 MIME 类型User-Agent发送请求的客户端软件信息
构造头信息
使用 headers 参数传入。通常使用字典格式。
headers {user-agent: my-app/0.0.1}
r requests.get(url, headersheaders) 代码示例
import requestsdef test_header():url https://httpbin.ceshiren.com/getheaders {name: LiMing, User-Agent: apple, Content-type: application/json}r requests.get(url, verifyFalse, headersheaders)print(r.json())5.接口请求体-json
接口请求体简介
进行HTTP请求时发送给服务器的数据。数据格式类型可以是JSON、XML、文本、图像等格式。请求体的格式和内容取决于服务器端API的设计和开发人员的要求。 常用接口请求体
类型介绍Content-typeJSONJavaScript Object Notation轻量级的数据交换格式最常见的一种类型。application/json表单数据Form Data以键值对的形式提交数据例如通过 HTML 表单提交数据。application/x-www-form-urlencodedXMLeXtensible Markup Language常用的标记语言通常用于传递配置文件等数据。application/xml text/xml文件File可以通过请求体上传文件数据例如上传图片、视频等文件。上传文件的 MIME 类型例如 image/jpeg multipart/form-data纯文本Text纯文本数据例如发送邮件、发送短信等场景text/plain其他格式二进制数据、protobuf 等格式
JSON 简介
是 JavaScript Object Notation 的缩写。是一种轻量级的数据交换格式。是理想的接口数据交换语言。Content-Type 为 application/json。 JSON 格式请求体示例
进入登录页面。打开开发者工具。输入用户名密码点击登录。https://litemall.hogwarts.ceshiren.com/#/login 构造 JSON 格式请求体
定义为字典格式。使用 json 参数传入。
import requestsdef test_request_body():url https://httpbin.ceshiren.com/postrequest_body {name: LiMing, teacher: Jenny}r requests.post(url, verifyFalse, jsonrequest_body)print(r.json())
6.接口响应断言 接口断言使用场景
问题 如何确保请求可以发送成功。如何保证符合业务需求。解决方案 通过获取响应信息验证接口请求是否成功是否符合业务需求。
Requests 中的响应结果对象
import requestsdef test_assert():url https://httpbin.ceshiren.com/getr requests.get(url, verifyFalse)print(r)
响应结果类型
属性含义r响应 Response 对象可以使用任意的变量名r.status_codeHTTP 响应状态码r.headers返回一个字典包含响应头的所有信息。r.text返回响应的内容是一个字符串。r.url编码之后的请求的 urlr.content返回响应的内容是一个字节流。r.raw响应的原始内容r.json()如果响应的内容是 JSON 格式可以使用该方法将其解析成 Python 对象。
代码示例
import requestsdef test_assert():url https://httpbin.ceshiren.com/getr requests.get(url, verifyFalse)print(------------------------------------------)print(r.status_code)print(------------------------------------------)print(r.headers)print(------------------------------------------)print(r.text)print(------------------------------------------)print(r.url)print(------------------------------------------)print(r.content)print(------------------------------------------)print(r.raw)print(------------------------------------------)print(r.json())
响应状态码断言
基础断言 r.status_code 代码示例
def test_assert_base():url https://httpbin.ceshiren.com/getr requests.get(url, verifyFalse)assert r.status_code 200 7.json响应体断言
什么是 JSON 响应体
JSON格式的响应体指的是HTTP响应中的消息体message body它是以JSON格式编码的数据。
{name: John,age: 30,city: New York
}
断言 JSON 格式响应体使用场景
验证API接口的返回结果是否符合预期。 业务场景上是否符合预期。格式是否符合文档规范。
断言 JSON 格式响应体
r.json()返回 python 字典。
import requestsdef test_res_json():r requests.get(https://httpbin.ceshiren.com/get)assert r.status_code 200assert r.json()[url] https://httpbin.ceshiren.com/get
代码示例
import requestsdef test_resonse_body_json():url https://httpbin.ceshiren.com/getr requests.get(url, verifyFalse)print(r.json())print(r.json()[headers])print(r.json()[headers][Host])assert r.status_code 200assert r.json()[url] https://httpbin.ceshiren.com/getdef test_resonse_body_json_fail():url https://www.baidu.comr requests.get(url)# 如果响应体是非 json 的场景那么就不要使用 r.json() 的方式否则则会# raise RequestsJSONDecodeError# print(r.json())# 可以使用r.textprint(r.text)assert r.status_code 200若碰到复杂断言应该如何处理
多层嵌套的数据提取与断言: JSONPath整体结构响应断言: JSONSchema自行编写解析算法 8.宠物商店接口自动化测试实战
被测产品
PetStore 宠物商城 一个在线的小型的商城。主要提供了增删查改等操作接口。结合 Swagger 实现了接口的管理。 需求说明
完成宠物商城宠物查询功能接口自动化测试。 编写自动化测试脚本。完成断言。 相关知识点
形式章节描述知识点接口请求方法http 接口请求方法构造知识点接口请求参数http 接口请求参数构造知识点接口请求体-jsonhttp 接口请求体为 json 格式知识点接口响应断言http 接口响应状态码断言 实战思路 宠物商店需求分析
被测产品宠物商店系统 - 查询宠物信息宠物商店接口文档https://petstore.swagger.io/
接口测试用例设计
宠物查询单接口用例 编写接口自动化测试脚本思路
查询宠物信息。 编写自动化测试脚本
test_petstore.py
import requestsfrom interface_automation_testing.接口自动化测试_L1.宠物商店接口自动化测试实战.utils.log_util import loggerclass TestPetstorePetsearch:def setup_class(self):# 定义接口请求 URLself.base_url https://petstore.swagger.io/v2/petself.search_url self.base_url /findByStatus# 【冒烟】传入available状态可以正确获取该状态下的宠物信息def test_search_pet1(self):# 查询接口请求参数params {status: available}# 发出查询请求r requests.get(self.search_url, paramsparams, verifyFalse)logger.info(【冒烟】传入available状态可以正确获取该状态下的宠物信息)# 状态断言assert r.status_code 200# 业务断言assert r.json() ! []assert id in r.json()[0]项目结构 脚本优化 - 添加日志
新建日志配置。在用例中使用配置好的日志实例。
import logging
import osfrom logging.handlers import RotatingFileHandler# 绑定绑定句柄到logger对象
logger logging.getLogger(__name__)# 获取当前工具文件所在的路径
root_path os.path.dirname(os.path.abspath(__file__))# 拼接当前要输出日志的路径
root_len len(root_path)
strs root_path[0:root_len-6]
log_dir_path os.sep.join([strs,fdatas\logs])if not os.path.isdir(log_dir_path):os.mkdir(log_dir_path)# 创建日志记录器指明日志保存路径,每个日志的大小保存日志的上限
file_log_handler RotatingFileHandler(os.sep.join([log_dir_path, log.log]),maxBytes1024 * 1024, backupCount10,encodingutf-8)# 设置日志的格式
date_string %Y-%m-%d %H:%M:%S
formatter logging.Formatter([%(asctime)s] [%(levelname)s] [%(filename)s]/[line: %(lineno)d]/[%(funcName)s] %(message)s ,date_string)# 日志输出到控制台的句柄
stream_handler logging.StreamHandler()# 将日志记录器指定日志的格式
file_log_handler.setFormatter(formatter)
stream_handler.setFormatter(formatter)# 为全局的日志工具对象添加日志记录器
# 绑定绑定句柄到logger对象
logger.addHandler(stream_handler)
logger.addHandler(file_log_handler)# 设置日志输出级别
logger.setLevel(levellogging.INFO)def prit_path():print(root_path)print(log_dir_path)prit_path()
脚本优化 - 参数化
使用 pytest parametrize 装饰器实现宠物状态的参数化。
test_petstore_parameterization.py
import pytest
import requestsfrom interface_automation_testing.接口自动化测试_L1.宠物商店接口自动化测试实战.utils.log_util import loggerclass TestPetstorePetsearch:def setup_class(self):# 定义接口请求 URLself.base_url https://petstore.swagger.io/v2/petself.search_url self.base_url /findByStatus# 【冒烟】传入available状态可以正确获取该状态下的宠物信息# 【冒烟】传入pending状态可以正确获取该状态下的宠物信息# 【冒烟】传入sold状态可以正确获取该状态下的宠物信息pytest.mark.parametrize(status,[available, pending, sold],ids[available_pets, pending_pets, sold_pets])def test_search_pet1(self, status):# 查询接口请求参数params {status: status}# 发出查询请求r requests.get(self.search_url, paramsparams, verifyFalse)logger.info(f【冒烟】传入{status}状态可以正确获取该状态下的宠物信息)# 状态断言assert r.status_code 200# 业务断言assert r.json() ! []assert id in r.json()[0]# 【异常】传入非指定状态字符串﹐响应为空# 【异常】传入非指定状态数字响应为空# 【异常】传入空字符串响应为空pytest.mark.parametrize(status,[petstatus, 123456, ],ids[petstatus_pets, 123456_pets, null_pets])def test_search_pet2(self, status):# 查询接口请求参数params {status: status}# 发出查询请求r requests.get(self.search_url, paramsparams, verifyFalse)logger.info(f【异常】传入{status}字符串﹐响应为空)# 状态断言assert r.status_code 200# 业务断言assert r.json() []# 【异常】不传入status响应为空def test_search_pet3(self):# 查询接口请求参数# 发出查询请求r requests.get(self.search_url, verifyFalse)logger.info(f【异常】不传入status响应为空)# 状态断言assert r.status_code 200# 业务断言assert r.json() []# 【异常】传入非status 的参数响应为空def test_search_pet4(self):# 查询接口请求参数params {key: available}# 发出查询请求r requests.get(self.search_url, paramsparams, verifyFalse)logger.info(f【异常】传入非status 的参数响应为空)# 状态断言assert r.status_code 200# 业务断言assert r.json() []生成测试报告
安装 allure 相关依赖。
# 生成报告信息
pytest --alluredir./report
# 生成报告在线服务查看报告
allure serve ./report/
pytest -vs .\test_petstore_parameterization.py --alluredir./datas/report --clean-alluredir运行结果 allure serve .\report\运行结果 总结
通过 Swagger 文档获取接口信息。使用 Requests 发出携带请求参数的 GET 请求。断言响应符合是否符合预期。添加 Log 日志。使用参数化方式实现一条用例可执行多个测试数据。生成 Allure 测试报告。
项目地址 template: 用来存放开发模版 - Gitee.com