【python做接口测试的学习记录day9——pytest自动化测试框架之yaml数据驱动封装】

之前我们的框架中,如果有多个测试用例,则需要在yaml文件中写入多个用例,而每个用例可能不同的仅仅只是个别参数值,这就导致很多重复代码,现在我们使用数据驱动就可以解决这个问题了。

我依旧采用之前的登录接口为例,简单记录一下数据驱动封装的全过程

DDT(data driver test)数据驱动yaml文件,对应的yaml测试用例文件为:get_token.yaml
- ['name','account','password','project','assert_str']
- ['登录成功获取token','admin','014f4041514bc5dcb82845fe5efa3c54','DEFAULT','data']
- ['登录失败密码错误','admin','123456','DEFAULT',40003]
- ['登录失败密码为空','admin','','DEFAULT',501]

第一行写入参数名称,后面你有几个用例就将用例对应的参数值写上,我这里写了用例名称、账户、密码、项目和断言,这里的参数名需要在之前的yaml用例文件中调用,因此我们修改下之前的get_token.yaml文件,如下:

-
  name: $ddt{name}
  parameterize:
    name-account-password-project-assert_str: /datas/get_token_data.yaml
  request:
    method: post
    url: /jlcloud/api/login
    headers:
      'Content-Type': 'application/json'
    json:
      account: $ddt{account}
      password: $ddt{password}
      project: $ddt{project}
      teacherLogin: false
      clientId: "1"
      secret: "test"
  extract:
    token: '"data":"(.*?)"'
  validate:
    - equals: {status_code: 200}
    - contains: $ddt{assert_str}

在yaml中调用的格式是$ddt{参数名},并且需要写入数据驱动 parameterize:
name-account-password-project-assert_str: /datas/get_token_data.yaml

驱动你这个用例的数据的读取,前面是参数,后面是读取的数据路径。

在common包下创建parameterize_util.py文件,这里需要写入我们读取的方法,并且我们在yaml_util中的读取测试用例的方法也需要写入到这里(在yaml_util.py中剪切read_testcase粘贴到parameterize_util.py),我们需要对这个这个方法加个判断,保证当用例大于等于2条也是可以使用的(即没使用数据驱动的多条用例yaml文件)

import json
from common.yaml_util import YamlUtil
import os
import yaml

读取测试用例
def read_testcase(yaml_name):
    with open(os.getcwd() + '\\testcases\\' + yaml_name, mode='r', encoding='utf-8') as f:
        caseinfo = yaml.load(f, yaml.FullLoader)
        if len(caseinfo)>=2:   #判断yaml用例文件中有几条用例,当用例大于等于2时,直接返回caseinfo
            return caseinfo
        else:                    #当等于1时,因为数据驱动后的caseinfo是字典列表我们就需要对caseinfo解包
            if "parameterize" in dict(*caseinfo).keys():
                new_caseinfo = ddt(*caseinfo)
                return new_caseinfo
            else:
                return caseinfo

def ddt(caseinfo):
    if "parameterize" in caseinfo.keys():
        caseinfo_str = json.dumps(caseinfo)  # 判断parameterize是否在caseinfo中
        for param_key, param_value in caseinfo["parameterize"].items():
            key_list = param_key.split("-")  # 将param_key转成列表
            data_list = YamlUtil().read_data(param_value)  # 读取param_value
            # 规范yaml数据文件的写法
            length_flag = True
            for data in data_list:
                if len(data) != len(key_list):
                    length_flag = False
                    break
            # 替换值
            new_caseinfo = []
            if length_flag:
                for x in range(1, len(data_list)):  # 循环数据的行数
                    temp_caseinfo = caseinfo_str
                    for y in range(0, len(data_list[x])):  # 循环数据列
                        if data_list[0][y] in key_list:
                            # 替换原始的yaml里面的$ddt{}
                            if isinstance(data_list[x][y], int) or isinstance(data_list[x][y], float):
                                temp_caseinfo = temp_caseinfo.replace('"$ddt{' + data_list[0][y] + '}"',
                                                                      str(data_list[x][y]))
                            else:
                                temp_caseinfo = temp_caseinfo.replace("$ddt{" + data_list[0][y] + "}",
                                                                      str(data_list[x][y]))
                    new_caseinfo.append(json.loads(temp_caseinfo))
        return new_caseinfo
    else:
        return caseinfo

这里因为read_testcase的方法不在yaml_util中了,所以我需要从common.parameterize_util 导入 ddt,read_testcase的方法并且调用,所以修改了test_login.py文件,代码如下:

import pytest
from common.request_util import RequestUtil
from test import Test
from common.parameterize_util import ddt,read_testcase

class TestRequest:
    pass
    @pytest.mark.parametrize("caseinfo",read_testcase('get_token.yaml'))
    def test_login(self,caseinfo):
        RequestUtil("base_test_url",Test()).standard_yaml(caseinfo)

    @pytest.mark.parametrize("caseinfo", read_testcase('userinfo.yaml'))
    def test_userinfo(self, caseinfo):
        RequestUtil("base_test_url", Test()).standard_yaml(caseinfo)

    @pytest.mark.parametrize("caseinfo", read_testcase('city_type.yaml'))
    def test_city(self, caseinfo):
       RequestUtil("base_test_url",Test()).standard_yaml(caseinfo)

    @pytest.mark.parametrize("caseinfo", read_testcase('mapid.yaml'))
    def test_mapid(self, caseinfo):
        RequestUtil("base_test_url", Test()).standard_yaml(caseinfo)

当后面的接口需要调用登录接口返回的token值,我们可以在数据驱动yaml文件中使用${read_extract_data(token)}调用,例如我的userinfo接口的yaml数据驱动文件:

DDT(data driver test)数据驱动yaml文件,对应的yaml测试用例文件为:userinfo.yaml
- ['name','token','assert_str']
- ['正确token成功获取用户信息','${read_extract_data(token)}','data']
- ['错误token无法获取用户信息','1', 40004]

在userinfo.yaml中直接使用$ddt{token}即可

-
  name: $ddt{name}
  parameterize:
    name-token-assert_str: /datas/userinfo_data.yaml
  request:
    method: get
    url: /jlcloud/api/login/getUserInfo
    params:
     token: $ddt{token}
    headers:
      'Content-Type': 'application/json'
  validate:
    - equals: { status_code: 200 }
    - contains: $ddt{assert_str}

这样就完成了我们的数据驱动封装,在以后添加修改测试用例只需要在datas包下,修改数据驱动yaml文件即可。

Original: https://blog.csdn.net/weixin_42833736/article/details/125652176
Author: 小丫么小二郎~
Title: 【python做接口测试的学习记录day9——pytest自动化测试框架之yaml数据驱动封装】

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/772674/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • TIPS:Ubuntu 系统python版本切换

    1、查看 (1)查看系统中存在的python版本: $ ls /usr/bin/python* (2)查看系统默认版本: $ python –version 2、修改 (1)基于…

    Python 2023年8月2日
    047
  • 【Python的自学之路】(二):学习python的基础知识

    可能还有人会问,python到底能用来干嘛,看了上面百度百科中【应用领域】内容的同学,其实应该已经了解了一部分了,我也不多赘述了。记住下面几点,都是我们后面一起要学习的内容。 1….

    Python 2023年9月18日
    049
  • Python | Pandas | 不完全总结

    本文对 Pandas 的使用进行不完全总结 1。 Updated: 2023 / 08 / 05 Python | Pandas | 不完全总结 数据类型 * 信息查询 类型转换 …

    Python 2023年8月19日
    051
  • 并发

    1并发、进程、线程的基本概念 1并发:提高速度 两个以上的任务(独立)同时发生; 2可执行程序 磁盘的一个文件,win的exe文件 3进程 可执行程序运行时,就创建了一个进程 4线…

    Python 2023年6月12日
    075
  • 为了防止这个公众号被封,我连夜用Python爬取了它所有图片~

    哈喽兄弟们,今天来试试批量获取公众号文章,emmm… 虽然名义上是文章,单其实它是一篇纯图片文,至于为什么不是文字,小姐姐不比文字香? ; 事前准备 我们需要用到 Fi…

    Python 2023年11月1日
    043
  • pytest之结合airtest生成allure和airtest报告

    定制报告 场景:希望在报告中看到测试功能,子功能,测试步骤, 用例描述,错误截图 解决: @Feature,story,step,description 步骤: Import al…

    Python 2023年9月11日
    052
  • Buuctf admin

    打开该靶机,发现为一个登陆的界面 总共有三个界面,分别为主界面,login登陆界面和register注册界面 根据标题,猜测应该是让我们用admin的用户去登陆 尝试对登陆界面进行…

    Python 2023年8月11日
    055
  • 小白之Python基础(五)

    使用dict和set 1、dict :是direction字典的缩写 1) 通过{ }创建,使用健-值(key-value)存储;用”键值对”表示映射关系,…

    Python 2023年5月23日
    070
  • 在 Python Django 框架中操作 MySQL 数据库

    本文目录 * – + * 一、查看是否安装 PyMySQL 驱动 * 二、安装 PyMySQL 驱动(若没有此驱动) * 三、配置数据库连接 * 四、为数据表创建模型 …

    Python 2023年8月3日
    060
  • 用Python实现简单的人脸识别,10分钟搞定!(附源码)

    前言 让我的电脑认识我,我的电脑只有认识我,才配称之为我的电脑! 今天,我们用Python实现简单的人脸识别技术! Python里,简单的人脸识别有很多种方法可以实现,依赖于pyt…

    Python 2023年9月26日
    044
  • python多线程

    一、多任务 1、多任务概念:同一时间执行多个任务2、多任务作用:充分利用CPU的资源,提高程序执行效率3、多任务的表现形式:并发:操作系统在执行多任务是交替执行并行:操作系统会给每…

    Python 2023年8月1日
    056
  • 【python】python基础_模块相关

    包:是一个包含多个模块的特殊目录,目录下有一个特殊的文件__init__.py(包名的命名方式和变量名一样)使用import 包名可以一次性导入包中所有的模块 1)创建startu…

    Python 2023年9月25日
    043
  • 数据分析–Matplotlib

    Matplotlib 基本布局对象 图表样式的修改以及图表装饰的接口 基础图表绘制 * 直方图 散点图 饼图 柱状图 折线图 表格 不同坐标系下的图象 matplotlib3D 基…

    Python 2023年9月1日
    077
  • Java阻塞队列中的异类,SynchronousQueue底层实现原理剖析

    上篇文章谈到BlockingQueue的使用场景,并重点分析了ArrayBlockingQueue的实现原理,了解到ArrayBlockingQueue底层是基于数组实现的阻塞队列…

    Python 2023年10月14日
    043
  • 基于用户评论情感分析详细设计与技术实现

    基于用户评论情感分析详细设计与技术实现 文章目录 基于用户评论情感分析详细设计与技术实现 前言 一、技术架构 二、分析服务器构建 * 1.1 创建flask项目 1.2 编写数据库…

    Python 2023年8月10日
    074
  • [django项目实战1]图书管理系统

    在上周经过了Django的学习后,(没看到可以点击此处)深入理解一个框架的意义就是直接使用其来进行开发。这里以简单的图书管理系统为例。其中,前端使用的是比较流行的Bootstrap…

    Python 2023年8月1日
    058
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球