在测试过程中经常会涉及到接口关联的,比如需要上一个接口返回的参数作为下一个接口的入参,这里就涉及到热加载,即让yaml文件可以调用外部函数。

一、提取上一个接口返回的参数保存到extract.yaml文件中

这里支持两种提取方式:正则表达式和jsonpath表达式提取

# 提取值并写入extract.yaml文件
                if "extract" in caseinfo.keys():
                    for key, value in caseinfo["extract"].items():
                        if "(.*?)" in value or "(.+?)" in value:        # 正则表达式
                            zz_value = re.search(value, return_text)
                            if zz_value:
                                extract_value = {key: zz_value.group(1)}
                                write_yaml(os.path.dirname(os.getcwd()) + '/run/extract.yaml', extract_value)
                        else:   # jsonpath
                            js_value = jsonpath.jsonpath(return_json, value)
                            if js_value:
                                extract_value = {key: js_value[0]}
                                write_yaml(os.path.dirname(os.getcwd()) + '/run/extract.yaml', extract_value)

   以jsonpath为例,接口响应是json串,提取jwt的值保存为token。

       

python3 yaml文件操作 python生成yaml文件_自动化测试

-
  name: $ddt{name}
  parameterize:
    name-userName-password-assert_str: /testdatas/get_user_data.yaml
  request:
    url: *******
    method: POST
    data:
      userName: $ddt{userName}
      password: $ddt{password}
  extract:
    token: $.jwt
  validate:
    - equals: {status_code: 200}
    - contains: $ddt{assert_str}

注意,这边是dict,不是list,token前面是没有-的。

二、在yaml用例中调用token

首先,创建hotloads文件夹,在文件夹下创建test.py文件,定义从extract.yaml文件中取值的方法。

#!/usr/bin/python3
# -*- coding:utf-8 -*-
# @Time : 2023/7/1 21:21
# @Author : 凌雪
# @File : test.py
# @Software: PyCharm
# 功能说明:热加载方法,在yaml用例中调用
from common.yaml_util import *
class Test:
    def read_extract_data(self,key):
        """
        从extract.yaml文件中读取动态参数值
        :param key: 动态参数名称
        :return: 动态参数值
        """
        return read_yaml(key)

然后,定义替换值的方法

def replace_value(self, data):
        """
        替换值的方法
        :param data:
        :return:
        """
        if data:
            data_type = type(data)      # 保存数据类型
            # 判断数据类型转换成str
            if isinstance(data, dict) or isinstance(data, list):
                str_data = json.dumps(data)
                print("str_data:" + str_data)
            else:
                str_data = str(data)
            for cs in range(1, str_data.count('${') + 1):
                # 替换
                if "${" in str_data and "}" in str_data:
                    start_index = str_data.index("${")
                    end_index = str_data.index("}", start_index)
                    old_value = str_data[start_index:end_index + 1]
                    # print("old_value:" + old_value)
                    # 反射:通过类的对象和方法字符串调用方法
                    func_name = old_value[2:old_value.index('(')]
                    # print("func_name:" + func_name)
                    args_value1 = old_value[old_value.index("(") + 1:old_value.index(")")]
                    new_value = ""
                    # new_value = read_yaml(old_value[2:-1])
                    # str_data = str_data.replace(old_value, new_value)
                    if args_value1 !="":
                        args_value2 = args_value1.split(',')
                        new_value = getattr(self.obj, func_name)(*args_value2)
                    else:
                        new_value = getattr(self.obj, func_name)()
                    str_data = str_data.replace(old_value, str(new_value))
            # 还原数据类型
            if isinstance(data, dict) or isinstance(data, list):
                data = json.loads(str_data)
            else:
                data = data_type(str_data)
        return data

在测试用例中调用要加载的方法类

#!/usr/bin/python3
# -*- coding:utf-8 -*-
# @Time : 2023/7/1 16:43
# @Author : 凌雪
# @File : test_swiper.py
# @Software: PyCharm
# 功能说明:******管理测试
import pytest
from common.send_request import Send_Request
from common.parameterize_util import ddt, read_testcase
import allure
from hotloads.test import Test
@allure.feature("****测试")
class TestHomepage:
    @allure.story("*****的接口")
    @pytest.mark.parametrize('testdata', read_testcase('swiper\\swiper.yaml'))
    def test_getheadinfo(self, testdata):
        res = Send_Request("trainurl", Test()).standard_yaml(testdata)

这边需要用到的是Test类中从extract.yaml文件中读取动态参数的方法,所以这里传的obj是Test()。

最后,在yaml用例中调用函数。

-
  name: ****列表
  request:
    url: ******
    method: GET
    headers:
      token: ${read_extract_data(token)}
    params:
      page: 1
      size: 20
      query:
      datatype: 3
  extract:
    lunboid: $.info.list[0].id
  validate:
    - equals: {statue: 200}
    - equals: {msg: 查询成功}