pytest实现用例间参数传递的方式

pytest实现用例间参数传递的方式

  • 一、通过conftest创建全局变量
  • 二、使用tmpdir_factory方法

我们在做接口自动化测试的时候,会经常遇到这种场景:接口A的返回结果中的某个字段,是接口B的某个字段的入参。如果是使用postman,那我们可以通过设置后置变量,然后在需要使用的地方通过{{}}的方式来进行调用。但是如果是使用自己写的测试框架中要如何实现呢?我想到的是如下三种方法。

首先说明一下,以下三种方式均是通过python + pytest来实现的

一、通过conftest创建全局变量

conftest.py文件是pytest框架中很有用的一个东西,首先看下官方文档中的解释:
在这里插入图片描述
大概意思就是说,conftest.py文件供整个用例目录(conftest.py文件可以有多个,并且只在当前package下生效)使用而无需导入,也就是说在用例目录是conftest中的信息是公用的,例如:

a/conftest.py:def pytest_runtest_setup(item):# called for running each test in 'a' directoryprint("setting up", item)a/test_sub.py:def test_sub():passtest_flat.py:def test_flat():pass

运行后的结果:

pytest test_flat.py --capture=no  # will not show "setting up"
pytest a/test_sub.py --capture=no  # will show "setting up"

而我们就可以通过conftest + fixture函数来实现我们想要的效果了,具体代码如下:`

# conftest.py# 定义一个全局变量,用于存储内容
global_data = {}@pytest.fixture
def set_global_data():"""设置全局变量,用于关联参数:return:"""def _set_global_data(key, value):global_data[key] = valuereturn _set_global_data@pytest.fixture
def get_global_data():"""从全局变量global_data中取值:return:"""def _get_global_data(key):return global_data.get(key)return _get_global_data

简单说一下实现逻辑:

首先定义一个变量global_data用于接收存储用例返回的结果
set_global_data和get_global_data两个fixture方法顾名思义,set方法是往global_data中存数据,get方法是从global_data中取数据

方法实现了,具体应该怎么使用呢?如下:

 
# test_get_set.pyimport requests
import pytestdef test_set(set_global_data):res = requests.get("http://www.baidu.com")status_code = res.status_codelogger.info(f"请求返回状态码:{status_code}")set_global_data("status_code", status_code)def test_get(get_global_data):data = get_global_data("status_code")logger.info(f'通过get_global_data方法获取的值:{data}')if __name__ == '__main__':pytest.main(['-sv', 'test_get_set.py'])

返回结果:

test_get_set.py::test_set PASSED
2021-12-24 17:58:37.642 | INFO     | cases.test_get_set:test_set:19 - 请求返回状态码:200
2021-12-24 17:58:37.643 | INFO     | cases.test_get_set:test_get:25 - 通过get_global_data方法获取的值:200
test_get_set.py::test_get PASSED============================== 2 passed in 0.06s ===============================

通过这种方式,便实现了用例间的参数传递问题。

在实际工作中,因为涉及到的接口、用例会很多,所以可以根据需要使用不同的conftest进行管理。并且存储的数据结构也需要进行规范区分,如使用方法名作为字典的key。

二、使用tmpdir_factory方法

第二种方法,是使用pytest的tmpdir和tmpdir_factory两个夹具函数,同样是通过conftest文件来实现。仍然是先来看下官方文档针对这两个方法的说明:
在这里插入图片描述
简单来说,这两个方法的作用就是为每个测试方法创建一个临时目录用于存储自定义的文件,这个临时目录会默认保存3个sessions,之后就会按照创建的顺序删除旧的目录。看下官方的例子:

# content of test_tmpdir.py
def test_create_file(tmpdir):p = tmpdir.mkdir("sub").join("hello.txt")p.write("content")assert p.read() == "content"assert len(tmpdir.listdir()) == 1assert 0
# contents of conftest.py
import pytest@pytest.fixture(scope="session")
def image_file(tmpdir_factory):img = compute_expensive_image()fn = tmpdir_factory.mktemp("data").join("img.png")img.save(str(fn))return fn# contents of test_image.py
def test_histogram(image_file):img = load_image(image_file)# compute and test histogram

我在实际项目中的使用:

仍是在conftest.py文件中自定义一个夹具函数,返回结果是一个元组,p是tmpdir_factory方法返回的对象,转为字符串之后就是文件存储的路径。

自定义一个名为“apitest-tmp-dir”的文件夹用于存储文件

# conftest.py@pytest.fixture
def tmp_factory(tmpdir_factory):"""生成临时目录"""p = tmpdir_factory.mktemp('apitest-tmp-dir')logger.info("当前临时文件的目录为:" + str(p))return p, str(p)

在测试方法中的使用

 
# test_get_set.pyimport requests
import pytest
import jsondef test_set(tmp_factory):res = requests.get("http://www.baidu.com")status_code = res.status_codelogger.info(f"返回状态码:{status_code}")logger.debug(tmp_factory)# 创建test_set.txt文件a = tmp_factory[0].join("test_set.txt")# 将需要的内容写入到文件中a.write({"status_code": status_code})# 使用read()方法获取文件中的内容logger.debug(a.read())if __name__ == '__main__':pytest.main(['-sv', 'test_get_set.py'])

返回结果:

test_get_set.py::test_set 2021-12-24 18:24:39.292 | INFO     | cases.conftest:tmp_factory:150 - 当前临时文件的目录为:/private/var/folders/_f/1d0lt83x1599bf6mcfppbwp40000gn/T/pytest-of-j/pytest-19/apitest-tmp-dir0
2021-12-24 18:24:39.347 | INFO     | cases.test_get_set:test_set:32 - 返回状态码:200
2021-12-24 18:24:39.347 | DEBUG    | cases.test_get_set:test_set:34 - (local('/private/var/folders/_f/1d0lt83x1599bf6mcfppbwp40000gn/T/pytest-of-j/pytest-19/apitest-tmp-dir0'), '/private/var/folders/_f/1d0lt83x1599bf6mcfppbwp40000gn/T/pytest-of-j/pytest-19/apitest-tmp-dir0')
2021-12-24 18:24:39.348 | DEBUG    | cases.test_get_set:test_set:38 - {'status_code': 200}
PASSED============================== 1 passed in 0.07s ===============================

创建的文件:
在这里插入图片描述

可以看到,tmpdir_factory会自动为我们创建一个目录,名字是tmp_factory方法中自定义的名称后面加0,同时它的上级目录会自动从pytest-0递增

说下这个办法的优缺点:

  • 先说优点,这种数据存储是直接写入到文件,因此即使运行结束后也可以访问,而不像第一种方法存储的内容会随着用例运行的结束而消失
  • 再说缺点,因为这个临时目录最多只能保存3个,因此如果用例很多时,那么就可能存在文件被自动删除的风险。不过这个貌似可以通过修改默认配置来解决,可以继续研究下。
    缺点二,上面的例子中,直接通过a.read()就访问到了文件中的内容,这是因为内容的存储与读取全是在一个方法内,因此可以直接调用。如果是A方法存结果,在B中需要读取,那么便不能直接使用read()方法了(因为每个方法都会创建一个目录,并且默认的读取地址都是这个方法自己创建的目录)。就需要我们自己去单独封装一个读取文件的方法了,实现起来也不难而且tmpdir本身的这些方法也是对os.path一些方法的二次封装。

话说回来,都需要我自己去封装一个读取文件的方法了,为啥不干脆把读、写都自己来做呢?这样是否删除文件、删除几个、什么时候删除就完全由自己定义了啊,貌似会更方便。。。。。

tmp_factory本身就是一个fixture函数,那么它就可以设定作用域function、class、module、session,设定之后是不是就可以解决文件覆盖的问题呢?在经过测试之后果然解决了问题,只要将tmp_factory的作用域改为session,那么就只会生成一个文件夹,至于文件全是根据用例名称创建的,完全没有影响的。只要再封装一个文件读取的函数就解决所有问题了。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Hive Metastore、Hive server和Hive thrift服务

Hive Metastore Hive Metastore是Hive的核心元数据管理服务,它提供了元数据的持久化存储和访问控制的能力,使得 Hive 成为一个强大的数据仓库和分析平台,适用于处理大数据和进行复杂的数据查询与分析任务。 Apache Hive是一个建立在 Apache Hadoop 上的数据仓库和分析工具…

ceph对象存储和安装dashborad

一、ceph–RadosGW对象存储 数据不需要放置在目录层次结构中,而是存在于平面地址空间内的同一级别; 应用通过唯一地址来识别每个单独的数据对象; 每个对象可包含有助于检索的元数据; 在Ceph中的对象存储网关中,通过RESTful API在…

opencv -11 图像运算之按位逻辑运算(图像融合图像修复和去除)

按位逻辑运算是一种对图像进行像素级别的逻辑操作的方法,使用OpenCV的按位逻辑运算函数可以对图像进行位与(AND)、位或(OR)、位非(NOT)和位异或(XOR)等操作。 通俗点就是…

郭东白的架构课学习笔笔记(1)

1.架构师的品质 自信和勇气(正确的废话)拥有战略意图,所谓战略意图,就是拥有与其资源和能力极不相称的雄心壮志。使用演绎法寻找架构原理,而不是归纳法。 2.如何提升自己的架构能力 向身边比自己厉害的优秀架构师或…

ubuntu 20.04 4090 显卡驱动安装 深度学习环境配置

1. 显卡驱动安装 准备工作: 换源安装输入法:重启的步骤先不管(自选)sudo apt update && sudo apt upgrade 禁用nouveau驱动(这个驱动是ubuntu开源小组逆向破解NVIDIA的开源驱动,与英伟达的原有驱…

设计模式之原型模式

写在前面 但我们看某个电影,或者是某个电视剧的时候,总会提到某某人是某某角色的原型,这里某某角色就好像是某某人的复制品一样,这里的原型设计模式也是如此,不过,这里的原型是一个对象,而原型…

云计算——云计算与虚拟化的关系

作者简介:一名云计算网络运维人员、每天分享网络与运维的技术与干货。 座右铭:低头赶路,敬事如仪 个人主页:网络豆的主页​​​​​ 目录 前言 一.虚拟化 1.什么是虚拟化 2.虚拟化技术作用 二.云计算与虚拟化的关系 三.虚…

ThunderScope开源示波器

简介 4CH,1GSa/S 开源示波器。前端很简洁,BUF802LMH6518,ADC是HMCAD1511,用Xilinx A7 FPGA进行控制,数据通过PCIE总线传输到上位机处理。目前这个项目已经被挂到了Xilinx官网,强。 设计日志:h…

【Docker】Docker镜像和Docker容器

文章目录 Docker镜像镜像基本概念为什么需要镜像?Union FS(联合文件挂载)docker镜像原理 Docker镜像命令docker rmidocker savedocker loaddocker historydocker image prune docker镜像实战离线迁移镜像镜像存储的压缩与共享 Docker容器容器…

Spring设计模式及部分技术讲解

讲师:邓澎波 Spring面试专题 1.Spring应该很熟悉吧?来介绍下你的Spring的理解 有些同学可能会抢答,不熟悉!!! 好了,不开玩笑,面对这个问题我们应该怎么来回答呢?我们给大家梳理这个几个维度来回答 1.1 Spring的发展历程 先介绍Spring是怎么来的,发展中有哪些核心的节…

mysql 2 -- 数据库基本操作、数据表的操作、mysql查询操作

一、数据库基本操作 1、数据库的登录及退出 连接数据库: mysql -u用户名 -h主机地址(省略代表本机) -p 密码(格式为123...);注: 刚下载安装的时候需要通过管理员进入 退出数据库,以下三种方式都可以: exit quit …

大数据学习02-Hadoop分布式集群部署

操作系统:centos7 软件环境:jdk8、hadoop-2.8.5 一、创建虚拟机 1.下载VMware,建议支持正版 2.安装到Widows目录下任意位置即可,安装目录自定义。打开VMware,界面如下: 3.创建虚拟机 创建虚拟机—>选择自定义 …