pytest之fixture参数化

1,420 阅读2分钟

pytest除了支持基本的测试用例参数化,还支持fixture参数化。当然,fixture参数化的过程与测试用例参数化有点点区别。 fixture的参数化涉及到fixture的参数params,和内置的fixture:request。

为一个参数的fixture参数化

import pytest

data = ["http://www.baidu.com", "https://www.google.com"]

@pytest.fixture(params=data)
def f_function(request):
    print("fixture部分:{}".format(request.param))
    return request.param

def test_add_by_func_1(f_function):
    print("测试用例:{}".format(f_function))

if __name__ == '__main__':
    pytest.main(['-v','-s'])
    
============================= test session starts ==============================
platform darwin -- Python 3.6.4, pytest-6.2.2, py-1.10.0, pluggy-0.13.1
rootdir: /Users/liuyan/PycharmProjects/pytest
plugins: allure-pytest-2.8.34collected 2 items

test_fixture_param.py fixture部分:http://www.baidu.com
.测试用例:http://www.baidu.com
fixture部分:https://www.google.com
.测试用例:https://www.google.com

其中,@pytest.fixture()中的params接收一个参数序列(列表或元组都可)。而request是内置fixture之一,它的一个属性param每次被传入params序列中的一个元素。从上面示例可以看出,fixture有一个参数,参数化时,我们为其提供了两个参数。

为多个参数的fixture参数化

如果是多个参数的fixture该怎样参数化呢,fixture的参数params接受的是一个参数序列,那么字典列表、字典元组这些都是序列,所以,我们可以借助字典来对多个参数进行参数化。

data = [{"url":"http://www.baidu.com","http":"get"}, {"url":"https://www.google.com","http":"post"}]

@pytest.fixture(params=data)
def f_function(request):
    print("fixture部分-url:{}".format(request.param['url']))
    print("fixture部分-http:{}".format(request.param['http']))
    return request.param

def test_add_by_func_2(f_function):
    print("测试用例:-url: {}".format(f_function['url']))
    print("测试用例:-http: {}".format(f_function['http']))

if __name__ == '__main__':
    pytest.main(['-v','-s'])
    
    
============================= test session starts ==============================
platform darwin -- Python 3.6.4, pytest-6.2.2, py-1.10.0, pluggy-0.13.1
rootdir: /Users/liuyan/PycharmProjects/pytest
plugins: allure-pytest-2.8.34collected 2 items

test_fixture_param.py fixture部分-url:http://www.baidu.com
fixture部分-http:get
.测试用例:-url: http://www.baidu.com
测试用例:-http: get
fixture部分-url:https://www.google.com
fixture部分-http:post
.测试用例:-url: https://www.google.com
测试用例:-http: post

fixture的参数:ids。为每一组参数打上标识。

该参数的作用,就是为了解决当多个参数的多组数据时,测试用例的标识问题的。 ids,顾名思义,就是为每一组测试参数指定一个独特的id,所以ids也是一个id列表,其长度和params的长度应该是一致的。

data = [{"url":"http://www.baidu.com","http":"get"}, {"url":"https://www.google.com","http":"post"}]

ids = ['get_baidu', 'post_google']


@pytest.fixture(params=data, ids=ids)
def f_function(request):
    print("fixture部分-url:{}".format(request.param['url']))
    print("fixture部分-http:{}".format(request.param['http']))
    return request.param

def test_add_by_func_2(f_function):
    print("测试用例:-url: {}".format(f_function['url']))
    print("测试用例:-http: {}".format(f_function['http']))

if __name__ == '__main__':
    pytest.main(['-v','-s'])

  
(ly_venv) liuyan@Lydemacpro pytest % pytest -v test_fixture_param.py 
============================= test session starts ==============================
platform darwin -- Python 3.6.4, pytest-6.2.2, py-1.10.0, pluggy-0.13.1 -- /Users/liuyan/ly_venv/bin/python
cachedir: .pytest_cache
metadata: {'Python': '3.6.4', 'Platform': 'Darwin-19.6.0-x86_64-i386-64bit', 'Packages': {'pytest': '6.2.2', 'py': '1.10.0', 'pluggy': '0.13.1'}, 'Plugins': {'allure-pytest': '2.8.34', 'html': '3.1.1', 'metadata': '1.11.0'}, 'JAVA_HOME': '/Library/Java/JavaVirtualMachines/jdk-12.0.2.jdk/Contents/Home'}
rootdir: /Users/liuyan/PycharmProjects/pytest
plugins: allure-pytest-2.8.34, html-3.1.1, metadata-1.11.0
collected 2 items                                                              

test_fixture_param.py::test_add_by_func_2[get_baidu] PASSED              [ 50%]
test_fixture_param.py::test_add_by_func_2[post_google] PASSED            [100%]