pytest 内置fixture-request

发布时间 2024-01-11 20:14:18作者: dack_deng

前言

pytest内置fixture是框架自带的一些fixtures,我们可以直接在用例中使用。参考官方文档https://docs.pytest.org/en/7.3.x/reference/reference.html
进入到官方文档,我们可以看到有许多内置fixtures,其中最重要的一个内置fixture是request。

1. 内置fixtures-request

1.1 request.param

request 是pytest的内置 fixture ,"为请求对象提供对请求测试上下文的访问权,并且在fixture被间接参数化的情况下具有可选的 “param” 属性。"这是官方文档对 request 的描述,官方文档对 request 是介绍非常简洁,总的来说就是有2个功能:

    1. 为请求对象提供对请求测试上下文的访问权,通俗来说就是全局的,可以在每个用例中调用
    1. 在 fixture 被间接参数化的情况下具有可选的“param”属性,通俗来说就是 fixture 也可以参数化
      查看request官方文档的描述:

      我们进行翻译。
要求
示例:根据命令行选项将不同的值传递给测试函数

该夹具是一种提供请求测试功能信息的特殊夹具。

夹具请求类
来自测试或固定装置功能的固定装置请求。

请求对象提供对请求测试上下文的访问,并具有可选属性,以防夹具间接参数化。param

夹具名称:可选[str]
正在执行此请求的夹具。

属性范围:_ScopeName
范围字符串,“函数”、“类”、“模块”、“包”、“会话”之一。

属性固定名称:List[str]
此请求中所有活动装置的名称。

属性节点
底层集合节点(取决于当前请求范围)。

属性配置:配置
与此请求关联的 pytest 配置对象。

属性函数
测试函数对象是否具有每个函数的范围。

属性集
收集测试函数的类(可以是 None)。

属性实例
收集测试函数的实例(可以是 None)。

属性模块
收集测试函数的 Python 模块对象。

属性路径:路径
收集测试函数的路径。

属性关键字:MutableMapping[str, Any]
底层节点的关键字/标记字典。

属性会话:会话
Pytest 会话对象。

addfinalizer(终结器)[来源]
添加在请求测试上下文中的最后一个测试完成执行后不带参数调用的终结器/拆卸函数。

应用标记(标记)[来源]
将标记应用于单个测试函数调用。

如果您不想在所有函数调用上都有关键字/标记,则此方法非常有用。

参数
marker (Union[str, MarkDecorator]) – 通过调用 .pytest.mark.NAME(...) 创建的对象

raiseerror(msg)[来源]
引发 FixtureLookupError 异常。

参数
msg (可选[str]) – 可选的自定义错误消息。

getfixturevalue(argname)[来源]
动态运行命名的固定功能。

建议尽可能通过函数参数声明装置。 但是,如果您只能在测试设置时决定是否使用另一个夹具,则可以使用此函数在夹具或测试函数体内检索它。

此方法可以在测试设置阶段或测试运行阶段使用,但在测试拆卸阶段,夹具的值可能不可用。

参数
argname (str) – 装置名称。

提高
pytest.FixtureLookupError – 如果找不到给定的装置。

看个示例。这个示例中,定义一个fixture,传入request参数,即可通过request.param获取到参数化传入的param参数。

import pytest

@pytest.fixture(params=['test'])
def fix_param(request):
    print(f'rrquest_param:{request.param}')
    return request.param

def test_fix_param(fix_param):
    print(f'传过来的fixture_param:{fix_param}')


此案例里面我们可以在 fixture 参数化的时候,通过request.param获取到测试的请求参数,但是在用例里面用request.param却不能获取到测试的请求参数。

import pytest

@pytest.fixture(params=['test'])
def fix_param(request):
    print(f'rrquest_param:{request.param}')
    return request.param

def test_fix_x(fix_param, request):
    print(f'传过来的fixture_param:{fix_param}')
    print(request.param)

1.2 request.module

fixture函数可以通过接受 request 对象来反向获取请求中的测试函数、类或模块上下文,进一步扩展我们已经写好的fixture,让我们从 fixture 的测试模块读取可选的服务器URL。conftest.py反向获取用例模块的server_url属性,作为环境地址。

# conftest.py

import pytest

@pytest.fixture(scope="module")
def server(request):
  server_url = getattr(request.module, "server_url", "https://www.baidu.com")
  print(f"fixture 获取到的server :{server_url}")
  return server_url

我们使用request.module属性来从测试模块中选择性地获取server_url属性,创建另一个test_y.py模块文件,在模块里面添加server_url属性,其中server_url为固定的,输入以下代码:

# test_y.py
server_url = "https://www.cnblogs.com"
def test_x(server):
  print(f"测试环境地址: {server}")

运行后:如果在test模块函数中,添加了server_url则优先获取模块中的,否则获取fixture中定义的:https://www.baidu.com

1.3 request.config

request.config用户获取测试的配置对象,在conftest.py写一个hook函数,pytest_addoption的作用是用于获取命令行参数,request.config用于读取测试的配置对象。

# conftest.py

import pytest
def pytest_addoption(parser):
    parser.addoption("--cmdopt", action="store", default="dack1", help="my option: dack1 or dack2")

@pytest.fixture
def cmdopt(request):
    return request.config.getoption("--cmdopt")

于是在测试用例里面可以通过 request.config来获取到配置参数,也可以通过自己定义的cmdopt来获取。

def test_answer_1(request):
    type = request.config.getoption("--cmdopt")
    print("获取到命令行参数:%s" % type)

def test_answer_2(cmdopt):
    print("获取到命令行参数:%s" % cmdopt)

1.4 request的其他成员对象

# conftest.py

@pytest.fixture(autouse=True)
def print_request(request):
    print("\n==========request start============")
    print(f"request.module: {request.module}")
    print(f"request.function: {request.function}")
    print(f"request.cls: {request.cls}")
    print(f"request.fspath: {request.fspath}")
    print(f"request.fixturenames: {request.fixturenames}")
    print(f"request.fixturename: {request.fixturename}")
    print(f"request.scope: {request.scope}")
    print(f"request.config: {request.config}")
    print("\n==========request end===============")


我们页可以通过打断点来查看request的全部属性对象。