用pytest创建动态参数?

Pyt*_*est 5 python pytest

我试图测试我的REST API的各种端点.一些端点采用其他端点提供的值.例如:

  • 查询/locations以获取可用位置列表以及是否已启用它们
  • 查询/inventory?loc_id=<id>并传入位置ID以获取特定位置的库存清单
  • 查询/inventory/<id>/details以获取与一个特定库存ID关联的属性列表

在我的测试中,我想要完成整个工作流程(检查特定位置的库存项目的特定属性).通常情况下,我会使用几个@parameterize装饰器构建一个pytest函数,但在这种情况下,我不会提前知道所有ID.

我通常做的事情:

@pytest.mark.parametrize('location', ['1', '2', '3', 'HQ'])
@pytest.mark.parametrize('inventory_id', [1, 2, 3])
def test_things(location, inventory_id):
    # Call /inventory/inventory_id/details and check attributes
Run Code Online (Sandbox Code Playgroud)

第二行是一个问题,因为我不知道inventory_ids没有/inventory先调用.它也完全有可能inventory_id在特定位置不可用.

我想做什么:

Query /location to build a list of IDs to add to the first parameterize line
Query `/inventory?loc_id=<id>` and build a list of IDs to pass to the second parameterize line
Run Code Online (Sandbox Code Playgroud)

我该如何动态构建这些线?

小智 10

如果您确实想使用每个 inventory_id 测试每个位置,您可以在测试之前计算这些列表

def get_locations_list(...):
    locations = []
    # query locations
    ...
    return locations

LOCATIONS = get_locations_list()
INVENTORY_IDS = get_inventory_ids()

@pytest.mark.parametrize('location', LOCATIONS)
@pytest.mark.parametrize('inventory_id', INVENTORY_IDS)
def test_things(location, inventory_id):
    # test stuff
Run Code Online (Sandbox Code Playgroud)

如果库存 ID 取决于位置,那么您可以准备元组列表:

def get_locations_and_ids():
    list_of_tuples = []
    ...
    for location in locations:
        ids = ...
        for id in ids:
            list_of_tuples.append( (location, id) )
    return list_of_tuples

LIST_OF_TUPLES = get_locations_and_ids()

@pytest.mark.parametrize(('location', 'inventory_id'), LIST_OF_TUPLES)
def test_things(location, inventory_id):
    # ...
Run Code Online (Sandbox Code Playgroud)

您还可以使用 pytest-generate-tests 模式,如下所述:

https://docs.pytest.org/en/latest/parametrize.html#basic-pytest-generate-tests-example


Ede*_*eca -1

您可以尝试 pytest.fixtures 为您的测试创建上下文,查看此处的文档

在这种情况下,您可以生成您需要的任何对象/值,例如:

import pytest

@pytest.fixture 
def inventory_id():
    return InventoryObject.id
Run Code Online (Sandbox Code Playgroud)

其他选项是使用vcrpy包。这允许您记录真实的 HTTP 调用并将其保存在文件中。