Python----Yaml数据驱动

本文介绍了如何使用Python读取和解析YAML文件以实现自动化测试中的数据驱动。通过YAML文件结构的解析,展示了如何结合CSV文件优化数据驱动,减少重复代码。文中还给出了读取YAML及CSV文件的函数实现,并展示了如何在测试用例中使用这些数据。
摘要由CSDN通过智能技术生成

Yaml数据驱动

1.本文浅浅介绍一下我是如何实现读取yaml文件的。

  • a.首先介绍一下yaml的结构类型:
    对象:键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)
    数组:一组按次序排列的值,又称为序列(sequence) / 列表(list)
    纯量(scalars):单个的、不可再分的值
  • b.语法法则:大小写敏感、使用缩进表示层级关系、缩进时不允许使用Tab键,只允许使用空格、缩进的空格数不重要,只要相同层级的元素左侧对齐即可

2.在自动化测试过程中我们可能会使用到yaml文件来实现数据驱动。在这里我将介绍yaml文件结合csv文件实现的数据驱动

3.自动化测试过程中,一个接口会存在多组测试用例,这时候我们就需要用到数据驱动来实现。yaml文件中的"-"就代表一项测试用例参数。由此可知,以下文件包含了两项测试用例,一个是登录成功、一个是登录失败。

# yaml文件中的测试用例
-
  name: 登录成功
  request:
    method: get
    url: /open/auth/Token
    data:
      app_key: 123456
      project_code: 123456
      method: 123456
  validate: True
  code: 0
-
  name: 登录失败
  request:
    method: get
    url: /open/auth/Token
    data:
      app_key: 
      project_code: 123456
      method: 123456
  validate: True
  code: 0

4.有了yaml文件我们就可以读取了:读取方法一

import yaml

BASE_PATH = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
# 入参yaml_name是要读取的yaml文件的名字
def read_testcases_yaml(yaml_name):
    # 得到yaml文件存放的位置
    data_file_path = os.path.join(BASE_PATH, "data")
    # 将文件路径进行拼接并打开文件
    with open(data_file_path + '/testdata/' + yaml_name, mode='r', encoding='utf-8') as f:
        # 使用yaml.load方法进行读取
        value = yaml.load(stream=f, Loader=yaml.FullLoader)
        return value

c.yaml文件读取方法二:由于我们的yaml文件中一个用例的参数可能大致上一致,不一致的只是value。所以当用例很多的时候我们就要重复的写很多次key、value。这里我们结合csv文件来优化一下

  • yaml文件:
-
 name: $csv{name}
 request:
   method: get
   url: /open/auth/Token
   data:
     app_key: $csv{app_key}
     project_code: 123456
     method: 123456
 validate: $csv{validate}
 boole: $csv{boole}
 code: 0
  • csv文件:
name,app_key,validate,boole
登录成功,123456,0,True
登录失败,,2006,False
  • 在这里我们同样需要读取yaml文件:
# 入参filename是要读取的yaml文件的名字
def read_yaml(filename, read_csv=True):
    """
   读取接口测试用例数据
   :param filename: 用例数据.yaml文件名
   :param read_csv: 是否读取csv文件,默认为True
   :return: 用例数据字典
   """
    # read_csv为True则读取对于csv文件,动态解析test_file中的变量
    filename = BASE_PATH + '/data/testdata/' + filename
    if read_csv:
        # 定义一个列表
        csv_list = []
        # 打开csv文件,这里由于我的csv文件名与yaml文件名一致所以替换后缀即可
        with open(filename.replace('yaml', 'csv'), 'r', encoding='utf-8') as f:
            # csv库提供了能直接将csv文件读取为字典的函数:DictReader()
            reader = csv.DictReader(f)
            for row in reader:
                # 创建一个字典
                csv_list.append(dict(row))
            # contextlib.ExitStack()管理多个上下文管理器
            with ExitStack() as stack:
                # 创建上下文管理器
                above_context = stack.enter_context(open(filename, 'r+', encoding='utf-8'))
               
                # 这是yaml列表中的每一项数据
                above_context_lines = above_context.readlines()
                # 定义一个列表
                ret = []
                # csv_list的长度即为动态解析后的测试用例数量
                for i in range(0, len(csv_list)):
                    testcase = ''
                    # 遍历列表字符串列表是否存在字符串形如$csv{...}
                    # new_line 是yaml文件一项数据的每一行
                    for new_line in above_context_lines:
                        # print("new line", new_line)
                        if re.search(r".+\$csv{(.+)}", new_line):
                            # group(0) 是获取取得的字符串整体,group(1)是取出括号⾥⾯我们要匹配的内容
                            temp_name = re.search(r".+\$csv{(.+)}", new_line).group(1)
                            temp_value = re.search(r".+:(.+)", new_line).group(1)
                            new_line = new_line.replace(temp_value.strip(), csv_list[i][temp_name])
                        testcase += new_line
                    # 把string转换成流的yaml工具包读取成列表
                    f = io.StringIO(testcase)
                    value = yaml.load(f, yaml.FullLoader)
                    ret.append(value[0])
                logger.debug("{}全部写入完成".format(ret))
        return ret
    else:
        # 读原yaml文件数据并返回
        return read_testcases_yaml(filename)
  • 读取到之后我们使用@pytest.mark.parametrize()获取参数。我们的断言和参数获取都可以进行进一步的封装,我这里是没有封装的。
    # 调用read_yaml方法,方法返回结果给到'case_info'
    @pytest.mark.parametrize('case_info', read_yaml('get_token.yaml'))
    # base_url是项目路径我写在了.ini文件中,可以在这里直接使用
    def test_get_token(self, case_info, base_url):
        # 由于参数是字典所以可以通过Key来获取value
        method = case_info['request']['method']
        url = base_url + case_info['request']['url']
        data = case_info['request']['data']
        # res 响应结果
        # 我这里的request已经简单封装好了
        res = RequestUtil().send_request(method, url, data)
        try:
            # 断言
            assert case_info['code'] == res.json()['code']
  • request的封装
import json

import requests


# 封装就意味着,这个方法要能够使用所有的请求
class RequestUtil:

    # 全局变量,类变量,通过类名调用
    sess = requests.session()

    def send_request(self, method, url, datas=None, **kwargs):
        # 将method参数转为小写字母的字符串类型
        method = str(method).lower()
        # 自定义变量res
        res = None
        if method == "get":
            res = RequestUtil.sess.request(method=method, url=url, params=datas, **kwargs)
        elif method == "post":
            # datas参数不为空,将datas参数装完Json格式
            if datas:
                datas = json.dumps(datas)
                res = RequestUtil.sess.request(method=method, url=url, data=datas, **kwargs)
        elif method == "put":
            print("内容")
        elif method == "delete":
            print("内容")
        else:
            pass
        # 返回发送请求成功后的响应结果
        return res

到这里简单的yaml文件的读取就结束啦,由于我也是刚刚接触所以写的不好,有不对的地方还请多多指教呀~

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值