接口自动化项目落地之HTTPBin网站

原文:https://www.cnblogs.com/df888/p/16011061.html
 

接口自动化项目落地系列

找个开源网站或开源项目,用tep实现整套pytest接口自动化项目落地,归档到电子书,作为tep完整教程项目篇一部分。自从tep完整教程发布以后,tep被越来越多小伙伴了解。教程只是纯理论,是骡子是马,拉出来遛遛才知道。做接口自动化项目落地,一方面是为了让自己脑海中的构想实实在在的呈现出来,现实和理想存在多少差距,不断尝试去弥补和修缮;另一方面也是方便读者朋友们学习使用,借助实际项目来练习,才能在赛道中弯道超车。

HTTPBin网站

httpbin.org是一个简单的在线提供HTTP服务的网站:

它能够用来对HTTP进行在线测试。

测试报告

HTTPBin网站的接口自动化项目包含11个用例集

67条测试用例

自动化执行正确率98.5%,其中有1条错误结果,是我故意为之的,因为想展示下断言失败的效果。

环境配置

包含http和https两套环境,因为HTTPBin支持HTTP&HTTPS:

fixtures/fixture_env_vars.py

#!/usr/bin/python
# encoding=utf-8from tep.fixture import *@pytest.fixture(scope="session")
def env_vars(config):class Clazz(TepVars):env = config["env"]"""变量定义开始"""# 环境变量mapping = {"http": {  # http环境"domain": "http://httpbin.org",},"https": {  # https环境"domain": "https://httpbin.org",}# 继续添加}# 定义类属性,敲代码时会自动补全domain = mapping[env]["domain"]"""变量定义结束"""return Clazz()

配置默认为http环境:

conf.yaml

env: http

用例集

http-methods

import allure
from tep.client import request@allure.title("get请求")
def test(env_vars):# 描述# 数据# 请求response = request("get",url=env_vars.domain + "/get",headers={'Host': 'httpbin.org', 'Proxy-Connection': 'keep-alive', 'accept': 'application/json','User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.109 Safari/537.36','Referer': 'http://httpbin.org/', 'Accept-Encoding': 'gzip, deflate','Accept-Language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7'},params={})# 提取# 断言assert response.status_code < 400

auth

import allure
from tep.client import request@allure.title("Authorization以Bearer开头,认证成功")
def test(env_vars):# 描述# http://httpbin.org/#/Auth/get_basic_auth__user___passwd_# 数据# 请求response = request("get",url=env_vars.domain + "/bearer",headers={'Host': 'httpbin.org', 'Proxy-Connection': 'keep-alive', 'accept': 'application/json','Authorization': 'Bearer ZG9uZ2ZhbmdlcjoxMjM0NTY=',  # 替换token'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.109 Safari/537.36','Referer': 'http://httpbin.org/', 'Accept-Encoding': 'gzip, deflate','Accept-Language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7'},params={})# 提取# 断言assert response.status_code < 400

status-codes

import allure
from tep.client import request@allure.title("post返回状态码300")
def test(env_vars):# 描述# 数据# 请求response = request("post",url=env_vars.domain + "/status/300",headers={'Host': 'httpbin.org', 'Proxy-Connection': 'keep-alive', 'Content-Length': '0', 'accept': 'text/plain','User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.109 Safari/537.36','Origin': 'http://httpbin.org', 'Referer': 'http://httpbin.org/', 'Accept-Encoding': 'gzip, deflate','Accept-Language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7','Cookie': 'stale_after=never; fake=fake_value'},json={})# 提取# 断言assert response.status_code == 300

request_inspection

import allure
from tep.client import request@allure.title("捕获请求信息--headers")
def test(env_vars):# 描述# 数据# 请求response = request("get",url=env_vars.domain + "/headers",headers={'Host': 'httpbin.org', 'Proxy-Connection': 'keep-alive', 'accept': 'application/json','User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.109 Safari/537.36','Referer': 'http://httpbin.org/', 'Accept-Encoding': 'gzip, deflate','Accept-Language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7','Cookie': 'stale_after=never; fake=fake_value'},params={})# 提取# 断言assert response.status_code < 400assert response.json()["headers"]

response_inspection

import allure
from tep.client import request@allure.title("捕获响应信息--缓存")
def test(env_vars):# 描述# 数据# 请求response = request("get",url=env_vars.domain + "/cache",headers={'Host': 'httpbin.org', 'Proxy-Connection': 'keep-alive', 'Cache-Control': 'max-age=0','accept': 'application/json', 'If-None-Match': '1', 'If-Modified-Since': '1','User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.109 Safari/537.36','Referer': 'http://httpbin.org/', 'Accept-Encoding': 'gzip, deflate','Accept-Language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7','Cookie': 'stale_after=never; fake=fake_value'},params={})# 提取# 断言assert response.status_code == 304

response_formats

import allure
from tep.client import request@allure.title("txt文本text/plain")
def test(env_vars):# 描述# 数据# 请求response = request("get",url=env_vars.domain + "/robots.txt",headers={'Host': 'httpbin.org', 'Proxy-Connection': 'keep-alive', 'accept': 'text/plain','User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.109 Safari/537.36','Referer': 'http://httpbin.org/', 'Accept-Encoding': 'gzip, deflate','Accept-Language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7','Cookie': 'stale_after=never; fake=fake_value'},params={})# 提取# 断言assert response.status_code < 400assert response.headers["content-type"] == "text/plain"

dynamic_data

import allure
from tep.client import request@allure.title("base64解码")
def test(env_vars):# 描述# 数据# 请求response = request("get",url=env_vars.domain + "/base64/SFRUUEJJTiBpcyBhd2Vzb21l",headers={'Host': 'httpbin.org', 'Proxy-Connection': 'keep-alive', 'accept': 'text/html','User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.109 Safari/537.36','Referer': 'http://httpbin.org/', 'Accept-Encoding': 'gzip, deflate','Accept-Language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7','Cookie': 'stale_after=never; fake=fake_value'},params={})# 提取# 断言assert response.status_code < 400assert "HTTPBIN is awesome" == response.text

cookies

import allure
from tep.client import request@allure.title("cookies")
def test(env_vars):# 描述# 数据# 请求response = request("get",url=env_vars.domain + "/cookies",headers={'Host': 'httpbin.org', 'Proxy-Connection': 'keep-alive', 'accept': 'application/json','User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.109 Safari/537.36','Referer': 'http://httpbin.org/', 'Accept-Encoding': 'gzip, deflate','Accept-Language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7','Cookie': 'stale_after=never; fake=fake_value'},params={})# 提取# 断言assert response.status_code < 400assert response.json()["cookies"]

images

import allure
from tep.client import request@allure.title("图片")
def test(env_vars):# 描述# 数据# 请求response = request("get",url=env_vars.domain + "/image",headers={'Host': 'httpbin.org', 'Proxy-Connection': 'keep-alive', 'accept': 'image/webp','User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.109 Safari/537.36','Referer': 'http://httpbin.org/', 'Accept-Encoding': 'gzip, deflate','Accept-Language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7','Cookie': 'stale_after=never; fake=fake_value; freeform=3; name=dongfanger'},params={})# 提取# 断言assert response.status_code < 400

redirects

import allure
from tep.client import request@allure.title("重定向")
def test(env_vars):# 描述# 数据# 请求response = request("get",url=env_vars.domain + "/redirect/1",headers={'Host': 'httpbin.org', 'Proxy-Connection': 'keep-alive', 'accept': 'text/html','User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.109 Safari/537.36','Referer': 'http://httpbin.org/', 'Accept-Encoding': 'gzip, deflate','Accept-Language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7','Cookie': 'stale_after=never; fake=fake_value; freeform=3; name=dongfanger'},params={})# 提取# 断言assert response.status_code == 404

anything

import allure
from tep.client import request@allure.title("返回所有数据")
def test(env_vars):# 描述# 数据# 请求response = request("delete",url=env_vars.domain + "/anything",headers={'Host': 'httpbin.org', 'Proxy-Connection': 'keep-alive', 'accept': 'application/json','User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.109 Safari/537.36','Origin': '', 'Referer': '/', 'Accept-Encoding': 'gzip, deflate','Accept-Language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7','Cookie': 'stale_after=never; fake=fake_value; freeform=3; name=dongfanger'},json={})# 提取# 断言assert response.status_code < 400# 描述# 数据# 请求response = request("get",url=env_vars.domain + "/anything",headers={'Host': 'httpbin.org', 'Proxy-Connection': 'keep-alive', 'accept': 'application/json','User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.109 Safari/537.36','Referer': '/', 'Accept-Encoding': 'gzip, deflate','Accept-Language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7','Cookie': 'stale_after=never; fake=fake_value; freeform=3; name=dongfanger'},params={})# 提取# 断言assert response.status_code < 400# 描述# 数据# 请求response = request("patch",url=env_vars.domain + "/anything",headers={'Host': 'httpbin.org', 'Proxy-Connection': 'keep-alive', 'accept': 'application/json','User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.109 Safari/537.36','Origin': '', 'Referer': '/', 'Accept-Encoding': 'gzip, deflate','Accept-Language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7','Cookie': 'stale_after=never; fake=fake_value; freeform=3; name=dongfanger'},json={})# 提取# 断言assert response.status_code < 400# 描述# 数据# 请求response = request("post",url=env_vars.domain + "/anything",headers={'Host': 'httpbin.org', 'Proxy-Connection': 'keep-alive', 'Content-Length': '0','accept': 'application/json','User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.109 Safari/537.36','Origin': '', 'Referer': '/', 'Accept-Encoding': 'gzip, deflate','Accept-Language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7','Cookie': 'stale_after=never; fake=fake_value; freeform=3; name=dongfanger'},json={})# 提取# 断言assert response.status_code < 400# 描述# 数据# 请求response = request("put",url=env_vars.domain + "/anything",headers={'Host': 'httpbin.org', 'Proxy-Connection': 'keep-alive', 'Content-Length': '0','accept': 'application/json','User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.109 Safari/537.36','Origin': '', 'Referer': '/', 'Accept-Encoding': 'gzip, deflate','Accept-Language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7','Cookie': 'stale_after=never; fake=fake_value; freeform=3; name=dongfanger'},json={})# 提取# 断言assert response.status_code < 400

只花了3小时完成

通过mitmproxy来录制流量自动生成用例,效率得到了极大的提高,从原来的1天缩短到3小时就完成了整个项目落地。相比于手工编写用例,这次写HTTPBin的接口自动化,我使用了utils/mitm.py来录制流量,mitmproxy稍微不方便的是需要手动开启代理,不过适应了以后还是能接受。录制流量后就会生成自动化用例,但是还需要二次修改,才会变成最终的用例。主要修改的工作量是在添加断言,根据业务设置合理的断言。其次是替换url为env_vars.domain + "/api"拼接方式,直接批量Replace即可。然后就是修改文件名和@allure.title了,给用例加上标题。工欲善其事,必先利其器。

tep共建

欢迎添加微信:cekaigang,分享交流tep实践案例,可以提供开源项目我来写,也可以写好后发我一起看看,优秀的项目会添加到tep完整教程的项目篇,以便更多测试同行们借鉴,大佬们赶快来加入我们吧。

参考资料:

HTTPBin接口自动化项目源码 GitHub - dongfanger/httpbin: httpbin.org接口自动化项目

postman Postman

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

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

相关文章

C语言:结构体

目录 结构体类型的声明 匿名结构体 全局结构体变量 嵌套结构体 访问结构体成员 结构的自引用 结构体变量的定义和初始化 结构体内存对齐 结构体内存对齐规则 修改默认对齐数 #pragma pack(n) offsetof 求结构体成员相对于结构体开头的偏移量的宏。 为什么存在内存…

pip list 和 conda list的区别

PS : 网上说conda activate了之后就可以随意pip了 可以conda和pip混用 但是安全起见还是尽量用pip 这样就算activate了&#xff0c;进入base虚拟环境了 conda与pip的区别 来源 Conda和pip通常被认为几乎完全相同。虽然这两个工具的某些功能重叠&#xff0c;但它们设计用于不…

硬件开发笔记(十二):RK3568底板电路电源模块和RTC模块原理图分析

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/134429973 红胖子网络科技博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬…

庖丁解牛:NIO核心概念与机制详解 06 _ 连网和异步 I/O

文章目录 Pre概述异步 I/OSelectors打开一个 ServerSocketChannel选择键内部循环监听新连接接受新的连接删除处理过的 SelectionKey传入的 I/O回到主循环 Pre 庖丁解牛&#xff1a;NIO核心概念与机制详解 01 庖丁解牛&#xff1a;NIO核心概念与机制详解 02 _ 缓冲区的细节实现…

如何将本地Portainer管理界面结合cpolar内网穿透工具实现远程浏览器访问

文章目录 前言1. 部署Portainer2. 本地访问Portainer3. Linux 安装cpolar4. 配置Portainer 公网访问地址5. 公网远程访问Portainer6. 固定Portainer公网地址 前言 Portainer 是一个轻量级的容器管理工具&#xff0c;可以通过 Web 界面对 Docker 容器进行管理和监控。它提供了可…

Android修行手册-POI操作中文API文档

Unity3D特效百例案例项目实战源码Android-Unity实战问题汇总游戏脚本-辅助自动化Android控件全解手册再战Android系列Scratch编程案例软考全系列Unity3D学习专栏蓝桥系列ChatGPT和AIGC &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分…

redis三种集群方式

redis有三种集群方式&#xff1a;主从复制&#xff0c;哨兵模式和集群。 1.主从复制 主从复制原理&#xff1a; 从服务器连接主服务器&#xff0c;发送SYNC命令&#xff1b; 主服务器接收到SYNC命名后&#xff0c;开始执行BGSAVE命令生成RDB文件并使用缓冲区记录此后执行的所…

键盘方向键移动当前选中的table单元格,并可以输入内容

有类似于这样的表格&#xff0c;用的<table>标签。原本要在单元格的文本框里面输入内容&#xff0c;需要用鼠标一个一个去点以获取焦点&#xff0c;现在需要不用鼠标选中&#xff0c;直接用键盘的上下左右来移动当前正在输入的单元格文本框。 const currentCell React.u…

【数据结构初阶】单链表SLlist

描述 不同于顺序表&#xff0c;顺序表的数据是存储在一个连续的空间里的 而链表它是链接起来的结构体地址。 所以我们不用像顺序表一样先创建一块空间出来&#xff0c;而是创建一个能存数据节点和节点与下一个节点之间的连接&#xff1b; 所以&#xff1a;“一个能存数据节点…

词向量笔记

一、词向量的世界排名比赛MTEB MTEB: Massive Text Embedding Benchmark 二、词向量的维数 词向量的维数d1一般取20~500之间

百分点科技|怎样做数据运营,才能让数据中台真正用起来?

导读&#xff1a;大多数企业用户已完成数据平台初步建设工作&#xff0c;但数据在业务运营和管理中没有发挥应有价值。数据开发工作繁重&#xff0c;数据质量问题严重&#xff0c;IT、数据和业务协作不畅&#xff0c;诸多问题依然困扰着企业用户的IT部门和数据部门。数据运营成…

起立科技(起鸿)在第25届高交会上展示透明OLED技术创新

第二十五届中国国际高新技术成果交易会 日期&#xff1a;2023年11月15日 地点&#xff1a;福田会展中心7号馆 深圳&#xff0c;2023年11月15日 — 起鸿科技&#xff0c;作为透明OLED领域的引领者&#xff0c;于今日参展了第二十五届中国国际高新技术成果交易会。这一展会将汇…

『亚马逊云科技产品测评』活动征文|通过lightsail一键搭建Drupal VS 手动部署

『亚马逊云科技产品测评』活动征文&#xff5c;通过lightsail一键搭建Drupal 提示&#xff1a;授权声明&#xff1a;本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 Developer Centre, 知乎&#xff0c;自媒体平台&#xff0c;第三方开发者媒体等亚…

微服务架构中的 熔断和降级

文章目录 熔断判定服务的健康状态服务恢复正常 降级跨服务降级自身服务提供有损服务具体案例分析 熔断 微服务架构中&#xff0c;如果需要保障可用性&#xff0c;其中一个方式就是 熔断。熔断在微服务架构里面是指 当微服务本身出现问题的时候&#xff0c;它会拒绝新的请求&am…

大学生如何免费认证,下载,安装MATLAB

下载 打开学校图书馆官网 选择版本后&#xff0c;点击下载 注册绑定个人认证 前提&#xff01;需要有学校邮箱【以edu.cn结尾的】 进入mathworks官网 注册账户 安装 下载完后&#xff0c;打开 选择&#xff1a;setup 安装程序 勾选&#xff1a;是&#xff1b;选择&#xf…

机器学习第10天:集成学习

文章目录 机器学习专栏 介绍 投票分类器 介绍 代码 核心代码 示例代码 软投票与硬投票 bagging与pasting 介绍 核心代码 随机森林 介绍 代码 结语 机器学习专栏 机器学习_Nowl的博客-CSDN博客 介绍 集成学习的思想是很直观的&#xff1a;多个人判断的结合往往比…

身份证阅读器和社保卡读卡器Harmony鸿蒙系统ArkTS语言SDK开发包

项目需求&#xff0c;用ArkTS新一代开发语言实现了在Harmony鸿蒙系统上面兼容身份证阅读器和社保卡读卡器&#xff0c;调用了DonseeDeviceLib.har这个读卡库。 需要注意的是&#xff0c;鸿蒙系统的app扩展名为.hap&#xff0c;本项目编译输出的应用为&#xff1a;entry-default…

下厨房网站月度最佳栏目菜谱数据获取及分析PLus

目录 概要 源数据获取 写Python代码爬取数据 Scala介绍与数据处理 1.Sacla介绍 2.Scala数据处理流程 数据可视化 最终大屏效果 小结 概要 本文的主题是获取下厨房网站月度最佳栏目近十年数据&#xff0c;最终进行数据清洗、处理后生成所需的数据库表&#xff0c;最终进…

JPA整合Sqlite解决Dialect报错问题, 最新版Hibernate6

前言 我个人项目中&#xff0c;不想使用太重的数据库&#xff0c;而内嵌数据库中SQLite又是最受欢迎的&#xff0c; 因此决定采用这个数据库。 可是JPA并不支持Sqlite&#xff0c;这篇文章就是记录如何解决这个问题的。 原因 JPA屏蔽了底层的各个数据库差异&#xff0c; 但是…

竞赛 题目:基于深度学习的中文对话问答机器人

文章目录 0 简介1 项目架构2 项目的主要过程2.1 数据清洗、预处理2.2 分桶2.3 训练 3 项目的整体结构4 重要的API4.1 LSTM cells部分&#xff1a;4.2 损失函数&#xff1a;4.3 搭建seq2seq框架&#xff1a;4.4 测试部分&#xff1a;4.5 评价NLP测试效果&#xff1a;4.6 梯度截断…