pytest之fixture参数化

背景

本文总结fixture参数化

说明

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

为一个参数的fixture参数化。

示例如下:为一个参数的fixture参数化。

# ./conftest.py

import pytest


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

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


# ./test_case/test_func.py
import pytest

def test_add_by_func_aaa(f_function):
	print("测试用例:{}".format(f_function))
	
# ./run_test.py
import pytest

if __name__ == '__main__':
	pytest.main(['-v','-s'])
	
'''
============================= test session starts =============================
platform win32 -- Python 3.7.0, pytest-5.3.4, py-1.8.1, pluggy-0.13.1 -- D:\Python3.7\python.exe
cachedir: .pytest_cache
rootdir: D:\Python3.7\project\pytest, inifile: pytest.ini
plugins: allure-pytest-2.8.9, rerunfailures-8.0
collecting ... collected 2 items

test_case/test_func.py::test_add_by_func_aaa[https://www.baidu.com] fixture部分:https://www.baidu.com
测试用例:https://www.baidu.com
PASSED
test_case/test_func.py::test_add_by_func_aaa[https://www.google.com] fixture部分:https://www.google.com
测试用例:https://www.google.com
PASSED

============================== 2 passed in 0.03s ==============================
[Finished in 1.4s]
	
'''

其中,
@pytest.fixture()中的params接收一个参数序列(列表或元组都可)。而requset是内置fixture之一,它的一个属性param每次被传入params序列中的一个元素。
从以上示例看出,fixture有一个参数,参数化时,我们为其提供了两个参数。如果这是在测试用例中,意味着这个fixture会根据两个参数执行两次。
但是fixture对象是供测试用例请求用的,所以不能只考虑fixture,需要结合请求该fixture的测试用例考虑
本示例中,test_add_by_func_aaa请求了该fixture,由于fixture的参数有2组数据,所以该用例也执行了2次。

为多个参数的fixture参数化。

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

# ./conftest.py

import pytest


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

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


# ./test_case/test_func.py
import pytest
def test_add_by_func_aaa(f_function):
	print("测试用例-url:{}".format(f_function['url']))
	print("测试用例-http:{}".format(f_function['http']))	

# ./run_test.py
import pytest

if __name__ == '__main__':
	pytest.main(['-v','-s'])
		
'''
============================= test session starts =============================
platform win32 -- Python 3.7.0, pytest-5.3.4, py-1.8.1, pluggy-0.13.1 -- D:\Python3.7\python.exe
cachedir: .pytest_cache
rootdir: D:\Python3.7\project\pytest, inifile: pytest.ini
plugins: allure-pytest-2.8.9, rerunfailures-8.0
collecting ... collected 2 items

test_case/test_func.py::test_add_by_func_aaa[f_function0] fixture部分-url:https://www.baidu.com
fixture部分-http:get
测试用例-url:https://www.baidu.com
测试用例-http:get
PASSED
test_case/test_func.py::test_add_by_func_aaa[f_function1] fixture部分-url:https://www.google.com
fixture部分-http:post
测试用例-url:https://www.google.com
测试用例-http:post
PASSED

============================== 2 passed in 0.05s ==============================
[Finished in 1.5s]
'''	

如果你仔细的话,会发现这一点:
test_case/test_func.py::test_add_by_func_aaa[f_function0]
test_case/test_func.py::test_add_by_func_aaa[f_function1]
由于有两组参数,test_add_by_func_aaa测试用例会执行两遍,标识测试用例的标志编程了fixture名字加一个数字,不能很直观的反应这两个用例有啥区别。
所以,我们需要了解fixture的另一个参数:ids

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

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

# ./conftest.py

import pytest


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

ids = ['get_baidu', 'post_google']

@pytest.fixture(scope='function', 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

# ./test_case/test_func.py
import pytest
def test_add_by_func_aaa(f_function):
	print("测试用例-url:{}".format(f_function['url']))
	print("测试用例-http:{}".format(f_function['http']))	

	
# ./run_test.py
import pytest

if __name__ == '__main__':
	pytest.main(['-v','-s'])
		
'''
============================= test session starts =============================
platform win32 -- Python 3.7.0, pytest-5.3.4, py-1.8.1, pluggy-0.13.1 -- D:\Python3.7\python.exe
cachedir: .pytest_cache
rootdir: D:\Python3.7\project\pytest, inifile: pytest.ini
plugins: allure-pytest-2.8.9, rerunfailures-8.0
collecting ... collected 2 items

test_case/test_func.py::test_add_by_func_aaa[get_baidu] fixture部分-url:https://www.baidu.com
fixture部分-http:get
测试用例-url:https://www.baidu.com
测试用例-http:get
PASSED
test_case/test_func.py::test_add_by_func_aaa[post_google] fixture部分-url:https://www.google.com
fixture部分-http:post
测试用例-url:https://www.google.com
测试用例-http:post
PASSED

============================== 2 passed in 0.04s ==============================
[Finished in 1.5s]
'''	
	

最后

想象这样一个场景,fixture的名字和测试用例的参数名字是一样的,那么测试用例执行时是把它当作fixture呢,还是参数呢。
对于该场景,pytest也有相应的处理。
但是这里不作这方面的总结,因为,我认为我自己反正是干不出把fixture和参数取同一个名字这种事情的。

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值