文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

pytest用例间参数传递的两种实现方式是怎样的

2023-06-22 05:57

关注

pytest用例间参数传递的两种实现方式是怎样的,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

前言

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

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

一、通过conftest创建全局变量

conftest.py文件是pytest框架中很有用的一个东西,首先看下官方文档中的解释:

pytest用例间参数传递的两种实现方式是怎样的

大概意思就是说,conftest.py文件供整个用例目录(conftest.py文件可以有多个,并且只在当前package下生效)使用而无需导入,也就是说在用例目录是conftest中的信息是公用的,例如:

a/conftest.py:    def pytest_runtest_setup(item):        # called for running each test in 'a' directory        print("setting up", item) a/test_sub.py:    def test_sub():        pass test_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.fixturedef set_global_data():    """    设置全局变量,用于关联参数    :return:    """     def _set_global_data(key, value):        global_data[key] = value     return _set_global_data @pytest.fixturedef get_global_data():    """    从全局变量global_data中取值    :return:    """     def _get_global_data(key):        return global_data.get(key)     return _get_global_data

简单说一下实现逻辑:

  1. 首先定义一个变量global_data用于接收存储用例返回的结果

  2. set_global_data和get_global_data两个fixture方法顾名思义,set方法是往global_data中存数据,get方法是从global_data中取数据

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

 # test_get_set.py import requestsimport pytest   def test_set(set_global_data):    res = requests.get("http://www.baidu.com")    status_code = res.status_code    logger.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文件来实现。仍然是先来看下官方文档针对这两个方法的说明:

pytest用例间参数传递的两种实现方式是怎样的

简单来说,这两个方法的作用就是为每个测试方法创建一个临时目录用于存储自定义的文件,这个临时目录会默认保存3个sessions,之后就会按照创建的顺序删除旧的目录。看下官方的例子:

# content of test_tmpdir.pydef test_create_file(tmpdir):    p = tmpdir.mkdir("sub").join("hello.txt")    p.write("content")    assert p.read() == "content"    assert len(tmpdir.listdir()) == 1    assert 0
# contents of conftest.pyimport 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.pydef test_histogram(image_file):    img = load_image(image_file)    # compute and test histogram

我在实际项目中的使用:

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

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

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

在测试方法中的使用

 # test_get_set.py import requestsimport pytestimport json  def test_set(tmp_factory):    res = requests.get("http://www.baidu.com")    status_code = res.status_code    logger.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 ===============================

创建的文件:

pytest用例间参数传递的两种实现方式是怎样的

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

说下这个办法的优缺点:

话说回来,都需要我自己去封装一个读取文件的方法了,为啥不干脆把读、写都自己来做呢?这样是否删除文件、删除几个、什么时候删除就完全由自己定义了啊,貌似会更方便。大家应该对这两种方法都有了一些了解,核心都是通过pytest的conftes.py文件来实现的。

看完上述内容,你们掌握pytest用例间参数传递的两种实现方式是怎样的的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注编程网行业资讯频道,感谢各位的阅读!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯