pytest文档84 - 把收集的 yaml 文件转成pytest 模块和用例

news2024/11/27 11:39:18

前言

前面实现了一个基础的读取yaml文件内容,当成用例去执行。虽然入门简单,但需要扩展功能,比如在 yaml 用例实现参数化,就不好扩展了。
因为它并不是一个真正的pytest的模块和用例,无法被钩子函数探测到。所以这篇会把yaml文件动态生成一个py模块,把yaml文件的数据,动态生成一个函数。

pytest 用例收集

pytest 用例收集默认是按test_*.py 模块收集,并且test_开头的函数当成用例来执行的

# test_sample.py
def test_demo():
    print("hello")


def test_login():
    print("world")

如果我们把上面的代码转成 yaml 文件

test_demo:
    print: hello

test_login:
    print: hello

在yaml文件中写两个key,对应函数名称,对应的值是执行python的对应函数。
整体思路是把yaml文件转成一个py模块,把yaml里面的键值对,转成函数和待执行的内容。

(题外话:看到这里,有人要 mmp 了,好好代码写到 py 文件不行,非得装逼写到 yaml 文件,不都是一样执行么?)
这就回到面试上了,你去面试时候,面试官问你,你的测试数据有没跟代码分离,有没用到数据驱动,参数化等等等。

为什么测试数据要跟代码分离呢?
面试官觉得好维护,写到代码不好维护。
其实真的好维护吗?
这里打个大大的问号,yaml 文件和 py 文件本质上都是一个文件,你写到 yaml 文件,数据格式写错了编辑器都无法知道,你写到py文件编辑器还能快速识别,并且编辑器还能跳转到对应功能上。

还有一个方面原因:
面试官觉得写代码不好在公司推广,因为大部分公司测试人员不会代码,需要推广自动化,就需用到低代码的框架,让人人都能参与进来。

通过数据驱动的方式,还有个好处就是平台化,平台化落地底层得用数据驱动执行,在平台上维护自动化测试数据,做出可视化,可维护和管理的平台。

pytest+yaml 数据驱动

在conftest.py 完成yaml用例的收集,并转成标准的pytest用例

import types
import yaml
from pathlib import Path
from _pytest.python import Module


def pytest_collect_file(file_path: Path, parent):
    if file_path.suffix == ".yml" and file_path.name.startswith("test"):
        pytest_module = Module.from_parent(parent, path=file_path)
        # 动态创建 module
        module = types.ModuleType(file_path.stem)
        print('module name:, ', module)
        # 解析 yaml 内容
        raw_dict = yaml.safe_load(file_path.open(encoding='utf-8'))
        print(raw_dict)
        # 用例名称test_开头
        for function_name, value in raw_dict.items():
            def function_template(*args, **kwargs):
                """
                测试用例-函数模块
                """
                for step_key, step_value in value.items():
                    # 执行用例里面的方法
                    eval(step_key)(step_value)
            # 向 module 中加入函数
            setattr(module, function_name, function_template)
            # 重写_getobj 属性
        pytest_module._getobj = lambda: module
        return pytest_module

test_login.yml测试用例

test_demo:
    print: hello

test_login:
    print: hello

执行pytest -s

会看到yaml文件中的数据,被转成了标准的pytest 函数式的用例。

执行接口用例

如果我们需要把接口的用例,转成yaml文件,如下示例

# test_sample.py
import requests


def request(*args, **kwargs):
    res = requests.Session().request(*args, **kwargs)
    print(res.text)
    return res


def test_demo():
    print("hello")


def test_login():
    req = {
        "url": "http://127.0.0.1:8000/api/v1/login",
        "method": "POST",
        "headers": {"Content-Type": "application/json"},
        "json": {"username": "test", "password": "123456"}
    }
    request(**req)

封装一个公共的请求方法request,只需要传接口参数就可以实现, 于是在yaml中可以这样写

test_demo:
    print: hello

test_login:
    request:
        url: http://124.70.221.221:8201/api/v1/login/
        method: POST
        headers:
            Content-Type: application/json
            User-Agent: python-requests/2.18.4
        json:
            username: test
            password: 123456

在conftest.py 文件中完成收集用例钩子

import types
import yaml
from pathlib import Path
from _pytest.python import Module
import requests


def request(*args, **kwargs):
    res = requests.Session().request(*args, **kwargs)
    print(res.text)
    return res


def pytest_collect_file(file_path: Path, parent):
    if file_path.suffix == ".yml" and file_path.name.startswith("test"):
        pytest_module = Module.from_parent(parent, path=file_path)
        # 动态创建 module
        module = types.ModuleType(file_path.stem)
        print('module name:, ', module)
        # 解析 yaml 内容
        raw_dict = yaml.safe_load(file_path.open(encoding='utf-8'))
        print(raw_dict)
        # 用例名称test_开头
        for function_name, value in raw_dict.items():
            def function_template(*args, **kwargs):
                """
                测试用例-函数模块
                """
                for step_key, step_value in value.items():
                    # 执行用例里面的方法
                    if step_key == 'request':
                        res = request(**step_value)
                    else:
                        eval(step_key)(step_value)
            # 向 module 中加入函数
            setattr(module, function_name, function_template)
            # 重写_getobj 属性
        pytest_module._getobj = lambda: module
        return pytest_module

于是 yaml 文件中的接口请求,就会被当成用例执行了。
学习思路来自这篇https://blog.csdn.net/Hogwartstester/article/details/126767687

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/49879.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CV攻城狮入门VIT(vision transformer)之旅——VIT原理详解篇

🍊作者简介:秃头小苏,致力于用最通俗的语言描述问题 🍊往期回顾:CV攻城狮入门VIT(vision transformer)之旅——近年超火的Transformer你再不了解就晚了! 🍊近期目标:写好专栏的每一篇…

Linux centos7.6 安装elasticsearch8.x (es8) 教程

系列-Linux centos7.6 安装elasticsearch8.x (es8) 教程 Linux centos7.6 安装elasticsearch8.x (es8) 教程_言之有李LAX的博客-CSDN博客 系列-linux安装elasticsearch-head (es可视化界面) linux安装elasticsearch-head (es可视化界面&am…

隆重推出 Incredibuild 10

变更可能来的很快,也可能来的很慢。但有时候,它真的值得我们等待。您并非每天都能目睹一个很棒的平台进一步发展成为一个不可思议(Incredible)的平台。今天,我们将正式发布最新版本——Incredibuild 10!经过…

SIMetrix导入MOS管参数的另一种方法

问题的提出 在采用SIMetrix 8.3软件进行E类放大器的仿真过程中,用到了NEXPERIA公司的NMOS管器件PMH550UNE, 但在SIMetrix 8.3的库中没有该器件,因此需要导入第三方库文件. 通常的办法是从生产该器件的公司网站上下载器件库文件,导入到SIMet…

《QDebug 2022年11月》

一、Qt Widgets 问题交流 二、Qt Quick 问题交流 1.QtQuick.Dialogs 1.x 中的 MessageDialog 触发两次 accepted 、rejected [QTBUG-94126] If inherit QApplication, the MessageDialog accepted signal is emitted twice. - Qt Bug Tracker 当使用 QApplication 而不是 Q…

React 中ref 的使用(类组件和函数组件)以及forwardRef 与 useImperativeHandle 详解

前言 在一个父组件中,我们想要获取到其中的节点元素或者子组件实例,从而直接调用其上面的方法。Class 类组件和函数组件是两种不同的写法。 1. Class 组件中使用ref 在 React 的 Class 组件中,我们通过 createRef 创建 ref class Parent …

传统制造企业进行数字化转型,是翻身还是翻船?

数实融合正在从可选项,变成每个行业都要面对的必选项,制造企业也从野蛮生长逐渐步入有序的数字化世界。 出品|产业家 2022年,疫情及经济环境全面淬炼了各行各业,大多数能有效应用数字化持续经营的企业成为幸存者,数字…

信号与进程间通信

目录结束进程结束后台进程结束前台进程信号基本概念接收信号发送信号代码演示接收信号函数(signal)SIG_IGNSIG_DFL自定义函数发送信号(kill)接收信号解决僵尸进程结束进程 结束后台进程 终端1:./main killed 终端2&a…

Linux系统编程(五)——Linux下的多线程

目录 0x01 线程概述 一、线程和进程的区别 二、线程和进程的虚拟地址空间 三、线程之间共享的非共享资源 四、NPTL 0x02 创建线程 0x03 终止线程 0x04 连接已终止的进程 0x05 线程的分离 0x06 线程取消 0x07 线程属性 0x08 线程同步 一、互斥锁 二、死锁 三、如何…

三肽Gly-Cys-Gly、88440-55-5

三肽Gly-Cys-Gly 编号:111774 CAS号:88440-55-5 三字母:H2N-Gly-Cys-Gly-COOH 描 述:羧肽酶 U 抑制剂(凝血酶可激活的纤维蛋白溶解抑制剂,TAFI),Ki 0.14 μM。编号: 111774 中文名称…

Java#29(集合进阶2---双列集合)

目录 一.Map------------双列集合-----------一次添加一对元素,如: 小明 99岁 1.特点: 2.Map中常见的API 3.Map集合的遍历方式 4.HashMap 5.LinkedHashMap 6.TreeMap 一.Map------------双列集合-----------一次添加一对元素,如: 小明 99岁 1.特点: (1)双列集合一次需要…

在嵌入式里面实现printf()类似的功能

学习C语言大多数都是从printf("hello world")开始的,对于printf的熟悉程度最高,在嵌入式编程中,实现printf函数有一种很标准的办法就是实现putch,绑定对应的串口输出,设置好波特率,使能串口就可以…

No module named ‘PyQt5.QtWebEngineWidgets‘kn-----已解决

1.情况说明 本人在学习PyQt5的时候遇到了 from PyQt5.QtWebEngineWidgets import * 报错的情况,原因就是ModuleNotFoundError: No module named PyQt5.QtWebEngineWidgets 没有PyQt5.QtWebEngineWidgets, 2.解决办法: 解决办法一&#xf…

最快最便捷的pytest使用allure测试报告

一、前言 最近通过群友了解到了allure这个报告,开始还不以为然,但还是逃不过真香定律。 经过试用之后,发现这个报告真的很好,很适合自动化测试结果的展示。下面说说我的探索历程吧。 选用的项目为Selenium自动化测试Pytest框架…

Day1使用Burpsuite抓包工具抓包,改变UA头使得手机和pc端界面互相转换

1.前期工作:安装Burpsuite工具这里网上有许多教程,大致步骤如下: 找到安装包然后解压缩,然后双击 安装jdk,然后就是配置环境变量,如果是默认jdk安装路径没有更改路径的话就是跟如下一样 配置如下&#xff…

跨平台开发方案的三个时代

跨平台开发从本质上讲是为了增加业务代码的复用率,减少因为要适配多个平台带来的工作量,从而降低开发成本。在提高业务专注度的同时,能够为用户提供一致的用户体验,实现“多快好省”的效果。 跨平台是跨哪些平台?怎么…

高视医疗在港交所招股:IPO募资要用于贷款,高铁塔为控股股东

11月30日,高视医疗(HK:02407)在港交所发布公告,拟全球发售1306.86万股股份,其中香港发售股份130.7万股,国际发售股份1176.16万股,另有15%超额配股权,于2022年11月30日至12月5日招股&…

Talk预告 | 亚马逊云科技上海人工智能研究院肖天骏:基于视频的自监督物体遮挡补全分割

本期为TechBeat人工智能社区第458期线上Talk! 北京时间11月30日(周三)20:00,亚马逊云科技上海人工智能研究院资深应用科学家——肖天骏的Talk将准时在TechBeat人工智能社区开播! 他与大家分享的主题是: “基于视频的自监督物体遮挡补全分割”…

请求和响应

目录1 请求对象1.1 请求对象介绍1.2 请求对象常用方法-获取各自路径1.3 请求对象常用方法-获取请求头信息1.4 请求对象常用方法-请求参数信息1.5 获取请求参数并封装对象1.5.1 手动封装方式1.5.2 反射封装方式1.5.3 工具类封装方式1.6 流对象获取请求信息1.7 中文乱码问题1.8 请…

可发生点击化学反应:1458576-00-5,Biotin-PEG4-alkyne,生物素-四聚乙二醇-炔

【中文名称】生物素-四聚乙二醇-炔,生物素-四聚乙二醇-丙炔基 【英文名称】 Biotin-PEG4-alkyne 【货号】Y-PE-2172 【CAS】1458576-00-5 【分子式】C21H35N3O6S 【分子量】457.58 【基团】alkyne 【纯度】95% 【规格】25mg,100mg,250mg 【是…