simple-pytest 框架使用指南

news2025/2/28 6:25:46

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/json
    token: $global{token}

cases:
  - case_name: "搜索-正常"
    # case_tag 支持参数avl、dis、only 不填则为avl,如果只传入only,则所有case 只会返回only的数据,也可以自定义打tag
    case_tag: avl
    assert:
      - eq: [ status_code, 200 ]
      - ne: [ $.data, "" ]
    sql: select * from projectInfo where project="bm-scm"
    extract_sql:
      id: $.id
    assert_sql:
      - eq: [ $.id, 1 ]
  - case_name: "搜索-超出范围"
    case_tag: avl
    params: "page=2&limit=10"
    assert:
      - eq: [ status_code, 200 ]
      - eq: [ $.data, [] ]
# login.yaml
title: "登录"
path: /login
method: POST
request_data:
  headers:
    Content-Type: application/json

cases:
  - case_name: "登录-正常"
    # case_tag 支持参数avl、dis、only 不填则为avl,如果只传入only,则所有case 只会返回only的数据,也可以自定义打tag
    case_tag: avl
    json: {"username": "user1", "password": "password1"}
    extract:
      token: $.token
    assert:
      - eq: [status_code, 200]
      - ne: [$.token, ""]


  - case_name: "登录-用户名为空"
    case_tag: avl
    json: { "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 pytest

from utils.assertion.assert_util import Assert
from utils.http_request import HttpRequest
from utils.read_file_data import ReadFileData


class 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_util


if __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 pytest

from 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 ReadFileData


class 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_util

        order_pays_response = HttpRequest.simple_request(order_pays_data)
        # print(order_pays_response.json())
        Assert(order_pays_response, order_pays_data.get("assert")).assert_util


if __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 json

import pytest

from 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 SqlRequest


class 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_util


if __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.coloradmin.cn/o/1473301.html

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

相关文章

JAVA高并发——CompletableFuture

CompletableFuture是Java 8新增的一个超大型工具类。为什么说它大呢?因为它实现了Future接口,而更重要的是,它也实现了CompletionStage接口。CompletionStage接口也是Java 8中新增的,它拥有多达40种方法!是的&#xff…

大数据职业技术培训包含哪些

技能提升认证考试,旨在通过优化整合涵盖学历教育、职业资格、技术水平和高新技术培训等各种教育培训资源,通过大数据行业政府引导,推进教育培训的社会化,开辟教育培训新途径,围绕大数据技术人才创新能力建设&#xff0…

k8s pv与pvc理解与实践

参考文章: https://blog.csdn.net/qq_41337034/article/details/117220475 一、 pv/pvc简述 Pv是指PersistentVolume,中文含义是持久化存储卷是对底层的共享存储的一种抽象,Pv由管理员进行配置和创建,只要包含存储能力&#xff…

vue3使用elementPlus进行table合并处理

elementPlus中table合并部分列 虚拟数据中公司下有多个客户,公司一样的客户,公司列需要合并,客户如果一样也需要合并进行展示,效果展示 const tableData ref([])自定定义自已想要的数据,一般都是通过接口拿到 //table…

CPU处理器NUMA架构简介

在实际工作中,经常遇到服务器是否开启NUMA、NUMA绑定几颗Core、跨NUMA节点访问的性能下降等等话题。那么NUMA作为非一致性内存访问的多处理器架构,在架构上有什么特性、与SMP架构有哪些不同,调优策略等,本文将作简要介绍。 1、CPU…

什么是SSH端口转发?

目录 前言: 一、SSH端口转发的概念 二、SSH端口转发的类型 2.1 本地端口转发 2.2 远程端口转发 2.3 动态端口转发 三、SSH端口转发的用途 3.1 安全远程访问 3.2 跨越网络限制 3.3 加密流量传输 3.4 跨越 NAT 网络 3.5 安全代理 四、总结 前言&#xff…

设计模式浅析(九) ·模板方法模式

设计模式浅析(九) 模板方法模式 日常叨逼叨 java设计模式浅析,如果觉得对你有帮助,记得一键三连,谢谢各位观众老爷😁😁 模板方法模式 概念 模板方法模式(Template Method Pattern)在Java中是…

【MATLAB】VMD_ MFE_SVM_LSTM 神经网络时序预测算法

有意向获取代码,请转文末观看代码获取方式~也可转原文链接获取~ 1 基本定义 VMD_MFE_SVM_LSTM神经网络时序预测算法是一种结合了变分模态分解(VMD)、多尺度特征提取(MFE)、支持向量机(SVM)和长…

Java+SpringBoot+Vue+MySQL:美食推荐系统的技术革新

✍✍计算机编程指导师 ⭐⭐个人介绍:自己非常喜欢研究技术问题!专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目:有源码或者技术上的问题欢迎在评论区一起讨论交流! ⚡⚡ Java实战 |…

启动spark-shell时报错java.lang.NumberFormatException: For input string: “0x100“

一、问题描述 安装完Spark后,启动spark shell时报错 java.lang.NumberFormatException: For input string: "0x100" 如下图: 二、解决办法 1.更换scala的版本 2.更改环境变量 使用vim编辑器打开用户的环境变量配置文件 vim ~/.bashrc s…

解锁财务信任,掌握企业业务合作中的倾听艺术

企业在经营管理过程中,经常会思考如何才能成为一个完美的财务业务融合体,实现业务合作的最大价值。当我们置身于企业战略规划的构建过程中,就会明显的感觉到,获得财务信任有助于指导团队做出重大决策并推动企业未来的行动。市场和…

【蓝桥杯单片机入门记录】动态数码管

目录 一、数码管动态显示概述 二、动态数码管原理图 (1)原理图 (2)动态数码管如何与芯片相连 (3)“此器件” ——>锁存器74HC573 三、动态数码管显示例程 (1)例程1&#xf…

Day02:Web架构前后端分离站Docker容器站集成软件站建站分配

目录 常规化站点部署 站库分离 前后端分离 集成软件搭建Web应用 Docker容器搭建Web应用 建立分配站 静态 与 伪静态 总结 章节知识点: 应用架构:Web/APP/云应用/三方服务/负载均衡等 安全产品:CDN/WAF/IDS/IPS/蜜罐/防火墙/杀毒等 渗…

react useRef用法

1&#xff0c;保存变量永远不丢失 import React, { useState,useRef } from react export default function App() { const [count,setcount] useState(0) var mycount useRef(0)//保存变量永远不丢失--useRef用的是闭包原理 return( <div> <button onClick{()>…

Linux笔记--硬链接与软链接

一、硬链接 1.inode和block 文件包含两部分数据&#xff1a;文件属性和实际内容&#xff0c;属性放在inode中&#xff0c;实际内容放在data block中。还有个超级区块&#xff08;superblock&#xff09;记录整个文件系统的整体信息&#xff0c;包括inode和block的总量&#x…

%00截断 [GKCTF 2020]cve版签到

打开题目 F12之后在Headers中发现hint 两者结合利用零字符截断使get_headers()请求到本地127.0.0. 结合链接 构造 ?urlhttp://127.0.0.1%00www.ctfhub.com 必须以123结尾 ?urlhttp://127.0.0.123%00www.ctfhub.com 得到flag 知识点&#xff1a; PHP中get_headers函数 g…

合并spark structured streaming处理流式数据产生的小文件

备注&#xff1a; By 远方时光原创&#xff0c;可转载&#xff0c;不能复制到其他平台 背景&#xff1a;做流批一体&#xff0c;湖仓一体的大数据架构&#xff0c;常见的做法就是 数据源->spark Streaming->ODS&#xff08;数据湖&#xff09;->spark streaming->…

如何让网页APP化 渐进式Web应用(PWA)

前言 大家上网应该发现有的网页说可以安装对应应用&#xff0c;结果这个应用好像就是个web&#xff0c;不像是应用&#xff0c;因为这里采用了PWA相关技术。 PWA&#xff0c;全称为渐进式Web应用&#xff08;Progressive Web Apps&#xff09;&#xff0c;是一种可以提供类似…

无法访问云服务器上部署的Docker容器(二)

说明&#xff1a;记录一次使用公网IP 接口地址无法访问阿里云服务接口的问题&#xff1b; 描述 最近&#xff0c;我使用Docker部署了jeecg-boot项目&#xff0c;部署过程都没有问题&#xff0c;也没有错误信息。部署完成后&#xff0c;通过下面的地址访问后端Swagger接口文档…

Facebook的虚拟社交愿景:元宇宙时代的新起点

在当今数字化时代&#xff0c;社交媒体已经成为人们生活中不可或缺的一部分。而随着科技的不断进步和社会的发展&#xff0c;元宇宙已经成为了人们关注的热点话题之一。作为社交媒体的领军企业之一&#xff0c;Facebook也在积极探索虚拟社交的未来&#xff0c;将其视为元宇宙时…