有测试问题请微信联系作者,备注来意(点击此处添加)
240
一名普通的测试打工人;专注自动化测试技术研究、实践、总结、分享、交流。
用我多年的经历,给大家带来更多实用的干货。
人若有志,就不会在半坡停止。

【接口自动化框架_进阶】python接口自动化框架之2.0版自建库

项目介绍

目前常见的接口自动化框架,数据维护方式分为两种,一种是维护到文件,另一种维护到代码中。

文件方式维护

优点:

  • 可读性和可维护性好
  • 易上手
    缺点:
  • 性能较差些
  • 用例设计和使用不灵活
  • 冗余数据较多
  • 扩展性差

代码中维护

优点:

  • 灵活性高
  • 性能高
  • 代码及数据复用率高

缺点:

  • 可读性和可维护性好差
  • 不易上手

为了更好的解决可维护性和灵活性及代码复用率,故对框架进行重新设计。

项目数据分析

接口信息

  • 用例标题
  • 请求地址
  • 请求方式
  • 请求数据(支持动态提取响应中数据、支持动态定义参数、支持取配置参数)
    • 必填参数
    • 所有参数
    • 参数化数据

测试数据

  • 测试用例(可进行动态修改、引用为前置或后置操作步骤)
  • 测试步骤维护
  • 测试断言
    • 默认断言
    • 预期结果和实际结果进行对比
    • 自定义断言(key,关键字,value表达式计算)
    • 自定义断言(自定义方法)

项目设计

运行环境

allure-pytest==2.8.17
jsonpath==0.82
loguru==0.5.1
pytest==6.0.1
pytest-assume==2.4.3
pytest-rerunfailures==9.1.1
python-magic-bin==0.4.14
PyYAML==6.0
ruamel.yaml==0.17.10
requests==2.24.0
base
tool
xlrd~=1.2.0
xlwt~=1.3.0
xlutils~=2.0.0
pdfplumber~=0.7.1
urllib3==1.25.11

可以使用pip来安装包 pip install -r requirements.txt

项目及业务功能介绍

用例数据维护

# yaml锚点格式(范围:文件全局): *xx
      # 字典数据维护使用锚点
      # - name: &AP "张三"        #设置锚点
      #  Introduce: *AP         #引入锚点,类似于 Introduce=AP
      #  <<: *AP                #合并锚点,类似于 example.push(AP)
# jsonpath查找数据格式(范围:参数、断言均可):   $.xx
# 替换字符串数据格式(范围:参数、断言均可):  $xx或${xx}
# 方法调用格式(范围:自定义断言):   fun

# ============================================== 公共参数 ==============================================
dict:
  name: &name "张三"
  age: &age 18
  config: &config add()



# ============================================== 用例数据 ==============================================
# home页-消息-新增
api_message_add:
  title: home页第一条用例
  url: /api/post/message
  method: POST
  required_parameter:
    $id: ${is}             # 支持数据池提取数据
    name: *name           # 支持yaml锚点
    age: *age                    # __init__.py文件中取配置数据
    sex: fun{add()}
    funap: *config
    ss: dd
  all_parameters:
    id: $id
    name: 张三
    age: 18
  json:
  files:
# 参数化用例
  parameterization: {
      "enable": [
        # [用例参数,{实际结果:预期结果}]
        [ True, True ],     # 不填写实际结果表达式,会用后面的预期结果生成默认的实际结果的表达式(默认表达式为$.data.itemList.0.%s)
        [False, {"$.data.itemLIst.0.plateNo": False}]
      ] #,
#      "plateNo": [
#        ["用例1", {"$.data.itemLIst.0.plateNo": "预期1"}],
#        ["用例2", {"$.data.itemLIst.0.plateNo": "预期1"}]
#      ],
#      "name": [
#        ["用例1", {"$.data.itemLIst.0.plateNo": "预期1"}],
#        ["用例2", {"$.data.itemLIst.0.plateNo": "预期1"}]
#      ]
    }

  Abnormal_parameter:

环境配置

用例编写

# -*- coding:utf-8 -*-
"""
@File: test_home.py
@Author: SanShu
@Time : 2024/12/7 16:16
@Description: 测试用例
"""
import time
import pytest
from loguru import logger
from base.base_case import BaseCaseExecute
from tool.data_process import TestDataProcess
from tool import case_data_generate, merge_dict


class TestHome:

    @pytest.mark.parametrize("case",  # 获取参数化用例数据
                             case_data_generate(
                                 TestDataProcess("home/home.yaml").get_test_case("api_message_add.parameterization")
                             )
                             )
    def test_home(self,
                  case,
                  test_preceding_step,  # 前置用例执行
                  test_next_step  # 后置用例执行
                  ):
        # 参数化用例
        param, data, expect = case
        # 指定用例文件位置及用例名称
        case_data = TestDataProcess("home/home.yaml").get_test_case("$.api_message_add")

        param_json = merge_dict(  # 两个表合并,第一个基表,若两个表有同一个字段则以第二个表数据为准
            case_data["required_parameter"],  # 基表数据
            {
                param: data,
                "name": str(time.time()),
                "age": 19  # 基表有此字段时,以此数据为准
            }
        )

        # file_Path = 'files/upload_file.xls'
        # file_Name = os.path.basename(file_Path)

        data = {
            'title': case_data["title"],  # 用例标题
            "step": None,
            "url": case_data["url"],
            "method": case_data["method"],
            "header": None,
            "params": None,
            "data": None,
            "json": param_json,
            "files": None,  # {file_Name: file_Path}
            'extract': {
                'name': param_json.get('name'),  # 当前请求中提取参数到数据池中
                "id": "$.data.id",  # 响应数据中提取参数
                "name2": "$.data.name"
            },
            "expect": {
                "$.success": True,
                "$.data.name": "李四",
                "$.data.id": "$.data.id"  # {响应结果}和{参数池数据}对比
            },
            "expect_custom": [  # 自定义断言
                {
                    "expect": "$id",  # 数据池中提取数据("$"为全局池中取数据,"$."响应结果中取数据)
                    "keyword": "==",
                    "actual": "$.data.aaa"  # 响应数据中提取数据("$"为全局池中取数据,"$."响应结果中取数据)
                },
                {
                    "expect": "$id",  # 数据池中提取数据("$"为全局池中取数据,"$."响应结果中取数据)
                    "keyword": "==",
                    "actual": "$.data.aaa"  # 响应数据中提取数据("$"为全局池中取数据,"$."响应结果中取数据)
                },
                {
                    "func": {  # 自定义断言方法
                        "name": "add",  # 自定义方法和关键字方法只能走一个
                        "params": ["$.data.aaa", "$id"]  # "$"为全局池中取数据,"$."响应结果中取数据
                    }
                },
                {
                    "func": {  # 自定义断言方法
                        "name": "add2",  # 自定义方法和关键字方法只能走一个
                        "params": ["$.data.aaa", "$id"]  # "$"为全局池中取数据,"$."响应结果中取数据
                    }
                }
            ]

            # "relation": {  # 存储用例id到池子中,建立关系,便于后续使用---未开放,根据需求而定
            #     # "id": ["6b7pf4jcmun7qechmnjvno5oqa"]
            # }
        }

        # 执行用例
        BaseCaseExecute(data).execute()

用例执行

测试报告

自建库



自建库构建及安装

常见问题

posted @ 2024-12-12 15:10  三叔测试笔记  阅读(19)  评论(0编辑  收藏  举报
返回顶部 跳转底部