基于Pytest + Yaml + Allure 实现Http协议接口自动化


背景

  公司原本有自己的自动化测试框架,涵盖了四个项目,采用excel存储用例,每个项目用的单元测试框架还不一样,接口和UI都写在了一起~~~

灵感来源

  GitHub上的 pytestDemo 和 HttpRunner

目录结构

  base ==>>  requests请求,返回结果类,测试数据对象化封装

config ==>> 域名,固定变量,数据库链接

public ==>> 测试数据处理,全局变量替换,log,自定义异常类等公共方法

testcase ==>> 测试用例

data.yml ==>> 测试数据

parametrize_query.csv ==>> 参数化数据

用例设计

1.**局限于pytest参数化形式 `@pytest.mark.parametrize` ,每个测试用例只能对应一个参数化文件**

2.保证测试用例py文件的简洁,每个用例格式基本固定,代码量少

3.统一的YAML文件格式

  有依赖的参数化接口

  有依赖的非参数化接口

4.参数化引用csv文件

用例格式

import pytest
from public.send_request import SendRequest
from public.log import logger
from public.sql_to_data import SqlToData
from public.help import get_data_path, os, fun_name, report_setting, report_step_setting, allure

data_path = get_data_path(os.path.dirname(__file__))
test_params = SqlToData().yaml_db_query(data_path)


@allure.severity(allure.severity_level.TRIVIAL)
@allure.epic(test_params.get("epic"))
@allure.feature(test_params.get("feature"))
class TestContinentInfo:

    def setup_class(self):
        self.extract = {}

    @pytest.mark.run(order=2)
    @pytest.mark.parametrize("data", test_params["test_page_query_case"].parametrize)
    def test_page_query_case(self, data):
        logger.info("*************** 开始执行用例 ***************")
        # 获取执行用例函数名
        name = fun_name()
        # 报告展示的测试步骤
        report_step_setting(test_params[name])

        test_params[name].parametrize = data
        result, self.extract, validate = SendRequest(test_params[name], self.extract).send_request()

        # 报告上展示的测试标题等
        report_setting(test_params[name])
        logger.info("*************** 结束执行用例 ***************\n")

有依赖的参数化接口 YAML格式

test_page_query_case:
  case_step_1: # 依赖接口名称<可随意命名>,和参数化接口数据同级,可依赖多个,非必填
    path: /login
    method: POST
    headers:
      Content-Type: application/json
    parametrize:
    body:
      username: wintest4
      password: "123456"
    extract:
      token: $.login_info.token
      username: $.login_info.username
    validate:
    - [ comparator: equal, check: msg, expect: 恭喜,登录成功!, jsonpath: "$.msg"] story: 用例--登录接口测试 title: 登录接口测试-预期成功 step: 登录接口测试 description: 该用例是针对 登录接口 的测试 path: /get/user method: get headers: Content-Type: application/json token: $token username: $username parametrize: ${parametrize.csv} # csv文件参数化 body: extract: id: $.data[0].id validate: story: 用例--查询某个用户信息接口测试-流程 title: 查询某个用户信息接口测试-预期成功-流程 step: 查询某个用户信息接口测试-流程 description: 该用例是针对 查询某个用户信息接口 的测试-流程 sql: sql_country_page: SELECT COUNT(*) AS num FROM BAS_COUNTRY bc epic: 测试demo feature: 测试demo

有依赖的非参数化接口 YAML格式

test_demo_info_case:
  login:
    path: /login
    method: POST
    headers:
      Content-Type: application/json
    parametrize:
      - [ ]
    body:
      username: wintest4
      password: "123456"
    extract:
      token: $.login_info.token
      username: $.login_info.username
    validate:
    - [ comparator: equal, check: msg, expect: 恭喜,登录成功!, jsonpath: "$.msg"] story: 用例--登录接口测试 title: 登录接口测试-预期成功 step: 登录接口测试 description: 该用例是针对 登录接口 的测试 query: path: /users/$username method: get headers: Content-Type: application/json token: $token username: $username parametrize: body: extract: validate: - [ comparator: equal, check: msg, expect: 查询成功, jsonpath: "$.msg"] story: 用例--查询某个用户信息接口测试 title: 查询某个用户信息接口测试-预期成功 step: 查询某个用户信息接口测试 description: 该用例是针对 查询某个用户信息接口 的测试

参数化csv文件格式

参数字段和断言字段之间空一格

 allure报告