simple-pytest 框架使用指南

news/2025/3/29 6:59:57/

simple-pytest 框架使用指南

  • 一、框架介绍
    • 简介
    • 框架理念:
    • 框架地址
  • 二、实现功能
  • 三、目录结构
  • 四、依赖库
  • 五、启动方式
  • 六、使用教程
    • 1、快速开始
      • 1.1、创建用例:
      • 1.2、生成py文件
      • 1.3、运行脚本
        • 1.3.1 单个脚本运行
        • 1.3.2 全部运行
      • 1.4 报告查看
    • 2、功能介绍
      • 2.1、单个接口http请求与断言
      • 2.2、长链路业务http请求与断言
      • 2.3、数据库断言
      • 2.4、变量设置
        • 2.4.1、全局变量
        • 2.4.2 系统配置变量
      • 2.5 前后置处理
      • 2.6 环境配置切换
      • 2.7 文件读取
      • 2.8 通知

一、框架介绍

简介

simple-pytest 框架主要参考了httprunner的yaml数据驱动部分设计思路,是基于 Pytest + Pytest-html+ Log + Yaml + Mysql 实现的简易版接口自动化框架。与httprunner不同的是,httprunner是个封装好的工具包,simple-pytest 是半封装的脚本,目的是让用户自己更容易学习Pytest工具,理解框架设计。

框架理念:

1、一个yaml就是一个接口,包含了接口的请求,断言等信息。
2、脚本执行使用pytest+python代码做逻辑处理,更加方便喜欢写代码的同学
3、让新手同学更加全面的理解pytest框架
4、为了
在学这个框架前,必备的一点常识是:
1、python基础语法
2、pytest基础包括用例执行,夹具使用等

框架地址

gitee: https://gitee.com/itestxs/simple-pytest

二、实现功能

  • yaml数据驱动:实现数据驱动隔离
  • 用例标签:在py脚本中可以通过case_tag做用例过滤
  • 全局变量池:实现接口之间的关联取值
  • 多断言:支持==,!=等多种断言,支持jsonpath的取值方式
  • sql数据库断言: 直接在yaml测试用例中写入查询的sql即可断言,无需编写代码
  • 自动生成用例代码: 在yaml文件中填写好测试用例, 可以转换为py脚本。

三、目录结构

- config ====>> 项目配置文件redis,mysql等
- data ====>> 测试数据文件管理
- logs ====>> 日志记录
- reports ====>> 结果报告,包括html
- test_cases ====>> 测试用例 ├── confset.py ====>> 测试夹具
- utils ====>> 各种工具类├── assertion ====>>  断言工具
- pytest.ini ====>> pytest配置文件
- conftest.py ====>> 全局夹具配置
- requirements.txt ====>> 相关依赖包文件
- run.py ====>> 执行用例入口文件

四、依赖库

requests==2.28.1
jsonpath==0.82
fastapi==0.88.0
pymysql==1.0.2
pyyaml==5.4.1
pytest==7.4.3
pytest-html==4.1.1
py==1.11.0

五、启动方式

1、先安装pip install requirements.txt
2、启用utils下的shopping_mock模块
3、运行run.py文件,然后,查看report的结果报告即可。

六、使用教程

1、快速开始

1.1、创建用例:

在data目录下创建yaml文件

主要的字段格式如下:
title:接口名字
base_url:域名地址,不填则默认取得setting的BASE_URL,如果填写了,则直接获取填写的
path:接口请求地址
method:请求方法
request_data:统一的请求参数,比如headers
cases:测试用例集合
case_name:测试用例名字,支持多个case_name年编写
case_tag:支持参数avl、dis、only 不填则为avl。其中avl就是可用的意思,dis不可用,only是代表只有当前用例生效。如果只传入only,则其他用例则不被执行,优先级是only>dis>avl。也可以自定义打tag
json:接口的请求体,可以直接输入字典格式(自动生成的用例不是字典格式)。请注意yaml的格式
params:接口的url请求参数。(待补充用例)
assert:断言,status_code是断言请求状态码。$.data是jsonpath的表达式,目前仅支持改表达式写法。目前支持的断言方式请在assert_type.py里查看包含,大于、不等于、等于一系列判断
sql:该case关联的sql,可以将该sql用来做前置还是以及后置
extract_sql:提起该sql的返回内容的某个字段存在变量池中,$.id 也是jsonpath表达式
assert_sql:sql的断言,用法同assert

yaml 模板用例如下:

title: "查询商品"
base_url: $config{BASE_URL}
path: /items
method: GET
request_data:headers:Content-Type: application/jsontoken: $global{token}cases:- case_name: "搜索-正常"# case_tag 支持参数avl、dis、only 不填则为avl,如果只传入only,则所有case 只会返回only的数据,也可以自定义打tagcase_tag: avlassert:- eq: [ status_code, 200 ]- ne: [ $.data, "" ]sql: select * from projectInfo where project="bm-scm"extract_sql:id: $.idassert_sql:- eq: [ $.id, 1 ]- case_name: "搜索-超出范围"case_tag: avlparams: "page=2&limit=10"assert:- eq: [ status_code, 200 ]- eq: [ $.data, [] ]
# login.yaml
title: "登录"
path: /login
method: POST
request_data:headers:Content-Type: application/jsoncases:- case_name: "登录-正常"# case_tag 支持参数avl、dis、only 不填则为avl,如果只传入only,则所有case 只会返回only的数据,也可以自定义打tagcase_tag: avljson: {"username": "user1", "password": "password1"}extract:token: $.tokenassert:- eq: [status_code, 200]- ne: [$.token, ""]- case_name: "登录-用户名为空"case_tag: avljson: { "username": "", "password": "password1" }assert:- eq: [status_code, 401]- eq: [$.detail, "Invalid username or password"]

1.2、生成py文件

在utils目录下的yaml_to_py文件main修改,yaml_to_pys批量转换整个data文件夹下的yaml文件,yaml_to_py转换指定的yaml文件,参数,cover代表是否覆盖,传入true,则会覆盖你现有的。

if __name__ == '__main__':yaml_to_pys()# yaml_to_py("login.yaml")

case_datas 为自动获取测试用例集,可以通过get_case_data(case_tag=“tag”)中的case_tag去过滤特定标签用例。

1.3、运行脚本

1.3.1 单个脚本运行

每个执行py脚本都可直接右击执行

1.3.2 全部运行

点击运行run文件,可以通过testenv 参数指定获取哪个环境的配置。

1.4 报告查看

如果是单个配置,则直接在当前test_cases目录下就可以看到,如果是run脚本执行,则报告统一放在reports
目前的报告格式是pytest-html。如果要用allure,则可以自己修改使用。

2、功能介绍

2.1、单个接口http请求与断言

    response = HttpRequest.simple_request(case_data)Assert(response, case_data.get("assert")).assert_util
#!/usr/bin/env python
# -*- coding: utf-8 -*-import pytestfrom utils.assertion.assert_util import Assert
from utils.http_request import HttpRequest
from utils.read_file_data import ReadFileDataclass TestLogin():case_datas = ReadFileData("login.yaml").get_case_data()  # get_case_data("tag") 自定义tag输入@pytest.mark.parametrize('case_data', case_datas, ids=generate_ids(case_datas))def test_login(self, case_data):response = HttpRequest.simple_request(case_data)Assert(response, case_data.get("assert")).assert_utilif __name__ == '__main__':pytest.main(["test_login.py"])

2.2、长链路业务http请求与断言

该功能是添加购车然后付款的流程。 彼此之间有接口依赖问题,通常解决依赖问题有两种

  • 第一种:使用框架自带的merge_cases_data函数
    test_data = merge_cases_data(add_carts_data, order_pays_data) # 将多个用例合并。merge_cases_data 是依赖接口合并,有两个默认规则,如果两个接口用例数一样多的,如[x,y],[A,B]那用例合并后结果就是[x,A] ,[y,B],如果两个接口用例数不一样,如[x] [A,B]那结果就是[x,A],[x,B],如[x,y] [A]那结果就是[x,A],[y,A]。
  • 第二种:自己编写代码逻辑。
    每个yaml就是一个接口。获取每个yaml的接口数据,然后获取用例后if else逻辑。如果接口之前有变量依赖,请借助全局变量去取。

import pytestfrom utils.assertion.assert_util import Assert
from utils.http_request import HttpRequest
from utils.merge_cases import merge_cases_data, generate_ids
from utils.read_file_data import ReadFileDataclass TestAddPay():add_carts_data = ReadFileData("add_carts.yaml").get_case_data()  # get_case_data("tag") 自定义tag输入order_pays_data = ReadFileData("order_pays.yaml").get_case_data()test_data = merge_cases_data(add_carts_data, order_pays_data) # 将多个用例合并print("testdata",test_data)@pytest.mark.parametrize('add_carts_data,order_pays_data', test_data, ids=generate_ids(test_data,"merge"))def test_add_pay(self, add_carts_data, order_pays_data):add_carts_response = HttpRequest.simple_request(add_carts_data)# print(add_carts_response.json())Assert(add_carts_response, add_carts_data.get("assert")).assert_utilorder_pays_response = HttpRequest.simple_request(order_pays_data)# print(order_pays_response.json())Assert(order_pays_response, order_pays_data.get("assert")).assert_utilif __name__ == '__main__':pytest.main(["test_add_pay.py"])

2.3、数据库断言

需要提前在config配置settings的MYSQL_CONFIG参数

data = SqlRequest.sql_request(case_data)
Assert(data, case_data.get("assert_sql")).sql_assert_util

如果要讲数据库字段提取出来,则写在

GlobalVars.update_global_vars(key=“data”, value=data) # 将参数手动添加到公共变量中

import jsonimport pytestfrom utils.assertion.assert_util import Assert
from utils.global_vars import GlobalVars
from utils.http_request import HttpRequest
from utils.read_file_data import ReadFileData
from utils.sql_reqeust import SqlRequestclass TestSearch():case_datas = ReadFileData("search_items.yaml").get_case_data()  # get_case_data("tag") 自定义tag输入print(case_datas)@pytest.mark.parametrize('case_data', case_datas, ids=generate_ids(case_datas))def test_search_items(self, case_data):response = HttpRequest.simple_request(case_data)print(response.json())Assert(response, case_data.get("assert")).assert_util# demo1-数据库断言写法# from utils.mysql_manager import db # 注意一定要在测试用例中引用,要不然会连接不上数据库# data = db.select_db('select * from projectInfo where project="bm-scm"')# print("data",data)# GlobalVars.update_global_vars(key="data", value=data) # 将参数手动添加到公共变量中# assert data["id"] == 1# demo2-数据库断言写法data = SqlRequest.sql_request(case_data)print("data", data)GlobalVars.update_global_vars(key="data", value=data) # 将参数手动添加到公共变量中Assert(data, case_data.get("assert_sql")).sql_assert_utilif __name__ == '__main__':pytest.main(["test_search_items.py"])

2.4、变量设置

主要的变量有两种,一个是全局变量,主要是接口数据库字段等值的传参使用。一个是配置变量,拿去配置里的信息。

2.4.1、全局变量

使用用法:使用$global{}关键字获取

$global{token}

以上例子是获取全局变量中token的变量
注意:全局变量如果命名重复会导致值被替换,请使用不同的变量名。

2.4.2 系统配置变量

配置变量获取的是config里的setting值,启动的时候,会自动获取当前环境的配置

$config{BASE_URL}

2.5 前后置处理

目前前后置处理由用户自己处理,较为常用的用法是,使用pytest的夹具功能

2.6 环境配置切换

使用testenv参数即可切换生产以及测试环境的配置。默认不填的情况下,使用的是测试环境的配置。配置读取的是settings里的信息

2.7 文件读取

read_file_data提供函数,支持读取json、yaml、csv、txt等文件

2.8 通知

在config settings下配置project、feishu_key信息,运行run脚本,即可发送飞书通知,注意只有运行run脚本才可以发送飞书通知
[图片]


http://www.ppmy.cn/news/1367005.html

相关文章

如何清空远程Git仓库中的所有文件和文件夹,并将其恢复为初始状态?

如何清空远程Git仓库中的所有文件和文件夹,并将其恢复为初始状态? 如何将一个已经存在的远程Git仓库恢复到初始状态?即清空所有文件和文件夹,使其完全空白。这可能是出于某些原因,比如想要重新开始仓库,或…

《TCP/IP详解 卷一》第8章 ICMPv4 和 ICMPv6

目录 8.1 引言 8.1.1 在IPv4和IPv6中的封装 8.2 ICMP 报文 8.2.1 ICMPv4 报文 8.2.2 ICMPv6 报文 8.2.3 处理ICMP报文 8.3 ICMP差错报文 8.3.1 扩展的ICMP和多部报文 8.3.2 目的不可达和数据包太大 8.3.3 重定向 8.3.4 ICMP 超时 8.3.5 参数问题 8.4 ICMP查询/信息…

高光谱遥感学习入门丨高光谱数据处理基础、Python和Matlab高光谱遥感数据处理

目录 ①Python高光谱遥感数据处理与高光谱遥感机器学习方法深度应用 ②Matlab高光谱遥感、数据处理与混合像元分解实践技术应用 ③高光谱遥感数值建模技术及在植被、水体、土壤信息提取领域应用 更多应用 高光谱遥感信息对于我们认识世界具有重要意义。尽管大部分物质在人眼…

【Rust】——结构体struct

🎃个人专栏: 🐬 算法设计与分析:算法设计与分析_IT闫的博客-CSDN博客 🐳Java基础:Java基础_IT闫的博客-CSDN博客 🐋c语言:c语言_IT闫的博客-CSDN博客 🐟MySQL&#xff1a…

NLP Seq2Seq模型

🍨 本文为[🔗365天深度学习训练营学习记录博客🍦 参考文章:365天深度学习训练营🍖 原作者:[K同学啊 | 接辅导、项目定制]\n🚀 文章来源:[K同学的学习圈子](https://www.yuque.com/mi…

MyBatis 学习(三)之 MyBatis 全局配置文件

目录 1 MyBatis 全局配置文件 2 properties 元素 3 setting 设置 4 typeAlianses 别名处理器 5 typeHandler 类型处理器 6 objectFacotry 对象工厂(了解) 7 plugins 插件(了解) 8 environments 运行环境 9 databaseIdPro…

Unity中URP实现水体(整理优化)

文章目录 前言一、优化水的深度1、我们把 水流动的方向 和 水深浅过渡值,整合到一个四维变量中2、修改 水体流动方向3、在片元着色器中,修改使用过渡变量 二、优化泡沫三、优化水下的扭曲1、修复原本扰动UV的计算 四、优化水面高光1、把高光强度、光滑度…

1. 开发环境搭建

文章目录 前端 前后端分离项目 前端:管理端web页面 , 用户端小程序后端:SpringBoot 前端 基于Nginx运行