如何参数化测试,从参数化夹具中获取参数?

时间:2016-05-09 20:21:27

标签: python python-2.7 parameters pytest fixtures

我提前道歉,重复1000次单词参数。我的用例如下。

我使用 pytest 来测试解析器,该解析器从在线商店中解析产品页面中的字段。

我已经对一个夹具进行了参数化,因此每个夹具都会导入一个产品的数据。根据数据,我的意思是HTML源代码和带有预期值的字段列表。接下来我有一个参数化测试,它带有一个元组列表( field 期望值),这样每个字段都有自己的测试。

基本上,"裸骨"问题会是这样的:

from pytest import fixture, mark

products = [
    {
    'text': 'bla bla', 
    'fields': [('bla', 0), ('foo', -1)]
    },
    {
    'text': 'foo bar', 
    'fields': [('bla', -1), ('foo', 0), ('bar', 4)]
    }
]

@fixture(params=products)
def product(request):
    return request.param


@mark.parametrize('field_key, field_value', product['fields'])
def test_parser(product, field_key, field_value):
    assert product['text'].find(field_key) == field_value

@mark.parametrize装饰器的上下文中,product未被解释为固定装置,因此 pytest 会返回:

TypeError: 'function' object has no attribute '__getitem__'

pytest 有很多内省魔法,我找不到解决方案。我看了this question,但这不是我想要的。有没有办法实现这个目标?感谢。

2 个答案:

答案 0 :(得分:2)

我认为你不需要固定装置来实现你的目标。

根据您的示例数据,这是一种可能的方式:

from pytest import mark


products = [
    {
        'text': 'bla bla',
        'fields': [('bla', 0), ('foo', -1)]
    },
    {
        'text': 'foo bar',
        'fields': [('bla', -1), ('foo', 0), ('bar', 4)]
    }
]

possible_params = []
for product in products:  # Iterate over the products to build all desired invocations
    for field_key, field_value in product['fields']:
        possible_params.append((product['text'], field_key, field_value))

@mark.parametrize('text,field_key,field_value', possible_params)
def test_parser(text, field_key, field_value):
    assert text.find(field_key) == field_value

答案 1 :(得分:1)

我能够运行(在Python3中),尽管测试失败了:

#!python3
from pytest import fixture, mark

Products = [
    {
        'text':   'bla bla',
        'fields': [('bla', 0), ('foo', -1)]
    },
    {
        'text':   'foo bar',
        'fields': [('bla', -1), ('foo', 0), ('bar', 1)]
    }
]

@fixture(scope="module",
        params=[(prod['text'], *tpl) for prod in Products for tpl in prod['fields']])
def product(request):
    return request.param


def test_parser(product):
    haystack,needle,index = product
    assert haystack.find(needle) == index