接口自动化项目落地之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-8

from 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 < 400
    assert 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 < 400
    assert 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 < 400
    assert "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 < 400
    assert 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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

WMS仓储管理系统的工作流程是什么

在当前的物流行业中&#xff0c;高效和精准的仓库管理被视为成功的关键。为了满足这一需求&#xff0c;WMS仓储管理系统应运而生。这个系统是物流中心的核心部分&#xff0c;可以显著提高仓库的运营效率&#xff0c;为现代物流管理带来前所未有的便捷。 WMS仓储管理系统的工作流…

josef约瑟 闭锁继电器 LB-7DG 100V 50HZ 导轨安装

LB-7型闭锁继电器 闭锁继电器LB-7导轨安装 一、用途 LB-7型闭锁继电器(以下简称继电器)用于发电厂及变电所内高压母线带电时防止和接地刀闸。 二、结构和工作原理 1、继电器按整流式原理构成&#xff0c;该继电器由变压器、电阻器、整流桥、滤波电容、极化继电器及指示灯组…

openGauss学习笔记-128 openGauss 数据库管理-设置透明数据加密(TDE)

文章目录 openGauss学习笔记-128 openGauss 数据库管理-设置透明数据加密&#xff08;TDE&#xff09;128.1 概述128.2 前提条件128.3 背景信息128.4 密钥管理机制128.5 表级加密方案128.6 创建加密表128.7 切换加密表加密开关128.8 对加密表进行密钥轮转 openGauss学习笔记-12…

php伪随机数

利用工具 php_mt_seed <?php // php 7.2function white_list() {return mt_rand();}echo white_list(), "\n";echo white_list(), "\n";echo white_list(), "\n"; 输入命令&#xff1a; ./php_mt_seed 1035656029 <?phpmt_srand(181095…

腐蚀监测常用技术及作用

上次我们介绍了设备状态监测中的红外热像技术>>热成像仪的工作原理及在工业设备状态监测中的应用&#xff0c;这次我们一起来探讨腐蚀监测技术方面的内容。 在工业领域中&#xff0c;腐蚀监测技术是腐蚀控制的重要部分和可靠而有效的手段。通过对设备的腐蚀情况进行监测和…

单片非晶磁性测量系统磁参量指标

1. 概述 单片非晶磁性测量系统是专用于测量非晶或纳米晶薄片(带)交流磁特性的装置&#xff0c;由精密励磁及测量装置 ( 40 Hz&#xff5e;65 Hz&#xff0c;可定制至400 Hz )、单片磁导计、全自动测量软件组成。使用该装置可在能耗、效率、材料均匀性/一致性、可靠性、整个生命…

自定义类使用ArrayList中的remove

Java中ArrayList对基础类型和字符串类型的删除操作&#xff0c;直接用remove方法即可。但是对于自定义的类来说&#xff0c;用remove方法删除不了&#xff0c;因为没有办法确定是否是要删除的对象。 ArrayList中remove源码是&#xff1a; public boolean remove(Object o) {if…

wvp gb28181 pro 推流列表功能

界面截图 功能说明 功能演示 客户端推流 ​​​​​​​手机端&#xff0c;使用芯象软件进行推流&#xff0c;支持ios、android 推流地址使用如下格式&#xff1a; rtsp://192.168.4.116:554/live/123?secret035c73f7-bb6b-4889-a715-d9eb2d1925cc 详细操作教程参考 【腾讯文…

Cesium 问题:输出的 纬度 latitude 是 0

文章目录 问题分析问题 在坐标转换的时候,出现如下问题 分析 在检查代码后,发现我将转换之前的高度默认设置为了 0 ,因此没能正确转换 let positionsOnCircle = [];// 圆面边缘的点 let numPoints = 360; for (let i

通过easyexcel实现数据导入功能

上一篇文章通过easyexcel导出数据到excel表格已经实现了简单的数据导出功能&#xff0c;这篇文章也介绍一下怎么通过easyexcel从excel表格中导入数据。 目录 一、前端代码 index.html index.js 二、后端代码 controller service SongServiceImpl 三、功能预览 四、后端…

电机应用开发-PID控制器参数整定

PID控制器参数整定 比例调节&#xff1a;调节作用快&#xff0c;系统一出现偏差&#xff0c;调节器立即将偏差放大输出。 积分调节&#xff1a;输出变化和输入偏差的积分成正比。输出不仅取决于偏差大小&#xff0c;还取决于偏差存在的时间。只要有偏差存在&#xff0c;尽管偏差…

7年经验之谈 —— 如何高效的开展app的性能测试?

APP性能测试是什么 从网上查了一下&#xff0c;貌似也没什么特别的定义&#xff0c;我这边根据自己的经验给出一个自己的定义&#xff0c;如有巧合纯属雷同。 客户端性能测试就是&#xff0c;从业务和用户的角度出发&#xff0c;设计合理且有效的性能测试场景&#xff0c;制定…

Androidstudio中build.gradle classpath如何添加

Androidstudio中build.gradle classpath如何添加 build.gradle classpath如何添加 build.gradle classpath如何添加 升级as之后&#xff0c;gradle版本也升级了&#xff0c;导致project的build.gradle中的写法也不一样了。 buildscript {repositories {google()mavenCentral(…

机器学习算法项目开发流程

机器学习算法是当今人工智能领域最重要的技术之一&#xff0c;它可以让计算机通过学习数据中的模式和规律来实现预测和决策。在实际应用中&#xff0c;开发一个成功的机器学习算法项目需要遵循一定的开发流程。本文将介绍一个常见的机器学习算法项目开发流程&#xff0c;帮助读…

Linux mmap 的作用是什么?

文章目录 1.简介2.相关函数3.mmap和常规文件操作的区别4.作用参考文献 1.简介 mmap&#xff08;memory map&#xff09;即内存映射&#xff0c;用于将一个文件或设备映射到进程的地址空间。 2.相关函数 创建映射函数&#xff1a; #include <sys/mman.h>void *mmap(v…

【Android】画面卡顿优化列表流畅度六(终篇)

上一篇&#xff1a; 【Android】画面卡顿优化列表流畅度五之下拉刷新上拉加载更多组件RefreshLayout修改 场景回顾&#xff1a; 业务经过一年半左右的运行后&#xff0c;出现了明显的列表卡顿情况&#xff1b;于是开始着手进行列表卡顿优化。目前的情况是&#xff1a; 网络图…

【18年扬大真题】给定有m个整数的递增有序数组a和有n个整数的递减有序数组b,将a数组和b数组归并为递增有序的数组c

【18年扬大真题】 给定有m个整数的递增有序数组a和有n个整数的递减有序数组b&#xff0c; 将a数组和b数组归并为递增有序的数组c。 void Merge(int arr[],int m ,int brr[],int n,int crr[]) {int i 0;int j n-1;int k 0;while(i < m&&j > 0) {if (arr[i] &l…

STM32 SPI

SPI介绍 SPI是Serial Pepheral interface缩写&#xff0c;串行外围设备接口。 SPI接口是一种高速的全双工同步通信总线&#xff0c;已经广泛应用在众多MCU、存储芯片、AD转换器和LCD之间。大部分STM32有3个SPI接口&#xff0c;本实验使用的是SPI1。 SPI同一时刻既能发送数据&…

简单模拟 Spring 创建的动态代理类(解释一种@Transactional事务失效的场景)

模拟 Spring 创建的动态代理类 本文主要目的是从父类和子类继承的角度去分析为什么在 Service 标注的业务类中使用 this 调用方法会造成事务失效。解释在这种情况下 this 为什么是原始类对象而不是代理类对象。 问题描述 在 Service 标注的业务类中&#xff0c;如果调用本类…

22年+21年 计算机能力挑战赛初赛C语言程序题 题解

22年 第14题&#xff1a;答案&#xff1a;33 #include<stdio.h> int x1; int f(int a) { static int x2;int n0;if(a%2){ static int x3;nx; }else { static int x5;nx; }return nx;} void main() { int sumx,i;for(i0;i<4;i) sumf(i); printf(&qu…