simple-pytest 框架使用指南

一、框架介绍

简介

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

框架理念:

1、一个yaml就是一个接口,包含了接口的请求,断言等信息。
2、脚本执行使用pytest+python代码做逻辑处理,更加方便喜欢写代码的同学
3、让新手同学更加全面的理解pytest框架

在学这个框架前,必备的一点常识是:
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_objects:sql集合,使用yaml锚点&定义变量,可在yaml中使用*引用变量
sql_object:sql 相关参数
    sql:该case关联的sql,可以将该sql用来做前置还是以及后置
    sql_tag: 支持数据库tag筛选
    execute_type: 该字段默认不填为query,支持exec与query两个类型
    extract_sql:提起该sql的返回内容的某个字段存在变量池中,$.id 也是jsonpath表达式
    assert_sql:sql的断言,用法同assert
    db_name: 选择指定哪个数据库连接

yaml 模板用例如下:

title: "查询商品"
base_url: $config{BASE_URL}
path: /items
method: GET
request_data:
  headers:
    Content-Type: application/json
    token: $global{token}
# 使用yaml 锚点&定义变量
sql_objects: &sql_objects
  - sql_object: &sql_object1
      sql: select * from projectInfo where project="tcm"
      sql_tag: avl
      # 该字段默认不填为query,支持exec与query两个类型
      execute_type: query
      # 多个sql提取的id变量名需要注意,不要重复
      extract_sql:
        id1: $.id
      assert_sql:
        - eq: [ $.id, 50 ]
      db_name: MYSQL_CONFIG
  - sql_object: &sql_object2
      sql: select * from projectInfo where project="tsf"
      sql_tag: avl
      extract_sql:
        id2: $.id
      db_name: MYSQL_CONFIG2

cases:
  - case_name: "搜索-正常"
    # case_tag 支持参数avl、dis、only 不填则为avl,如果只传入only,则所有case 只会返回only的数据,也可以自定义打tag
    case_tag: avl
    assert:
      - eq: [ status_code, 200 ]
      - ne: [ $.data, "" ]
    ref_sql:
      # 或直接引用整个对象 - *sql_objects
      - *sql_object1
      - *sql_object2
  - 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、数据库断言

  sql_datas = SqlRequest.get_sql_data(case_data) # 支持get_sql_data(sql_tag=“tag”) 用例按照tag筛选
  execute_sql_assert(sql_datas) # 数据库执行以及断言,支持多个数据库多个库的断言,如果断言为空,则会跳过断言
如果要将数据库字段提取出来,则需要修改execute_sql_assert函数逻辑,加上
  GlobalVars.update_global_vars(key=“data”, value=data) # 将sql执行结果添加到公共变量中


import pytest

from utils.assertion.assert_util import Assert
from utils.http_request import HttpRequest
from utils.merge_cases import generate_ids
from utils.read_file_data import ReadFileData
from utils.sql_reqeust import SqlRequest, execute_sql_assert


class TestSearch():
   case_datas = ReadFileData("search_items.yaml").get_case_data()  # get_case_data(case_tag="tag") 用例按照tag筛选

   @pytest.mark.parametrize('case_data', case_datas, ids=generate_ids(case_datas))
   def test_search_items(self, case_data):
       print("case_data", case_data)
       response = HttpRequest.simple_request(case_data)
       print(response.json())
       Assert(response, case_data.get("assert")).assert_util

       # demo-数据库断言写法
       sql_datas = SqlRequest.get_sql_data(case_data) # get_sql_data(sql_tag="tag") 用例按照tag筛选
       execute_sql_assert(sql_datas) # 数据库执行以及断言


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脚本才可以发送飞书通知
[图片]

  • 29
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
旅游社交小程序功能有管理员和用户。管理员有个人中心,用户管理,每日签到管理,景点推荐管理,景点分类管理,防疫查询管理,美食推荐管理,酒店推荐管理,周边推荐管理,分享圈管理,我的收藏管理,系统管理。用户可以在微信小程序上注册登录,进行每日签到,防疫查询,可以在分享圈里面进行分享自己想要分享的内容,查看和收藏景点以及美食的推荐等操作。因而具有一定的实用性。 本站后台采用Java的SSM框架进行后台管理开发,可以在浏览器上登录进行后台数据方面的管理,MySQL作为本地数据库,微信小程序用到了微信开发者工具,充分保证系统的稳定性。系统具有界面清晰、操作简单,功能齐全的特点,使得旅游社交小程序管理工作系统化、规范化。 管理员可以管理用户信息,可以对用户信息添加修改删除。管理员可以对景点推荐信息进行添加修改删除操作。管理员可以对分享圈信息进行添加,修改,删除操作。管理员可以对美食推荐信息进行添加,修改,删除操作。管理员可以对酒店推荐信息进行添加,修改,删除操作。管理员可以对周边推荐信息进行添加,修改,删除操作。 小程序用户是需要注册才可以进行登录的,登录后在首页可以查看相关信息,并且下面导航可以点击到其他功能模块。在小程序里点击我的,会出现关于我的界面,在这里可以修改个人信息,以及可以点击其他功能模块。用户想要把一些信息分享到分享圈的时候,可以点击新增,然后输入自己想要分享的信息就可以进行分享圈的操作。用户可以在景点推荐里面进行收藏和评论等操作。用户可以在美食推荐模块搜索和查看美食推荐的相关信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值