栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

pytest合集(7)— 参数化

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

pytest合集(7)— 参数化

一、pytest.mark.parametrize()

语法糖:

parametrize(argnames, argvalues, indirect=False, ids=None, scope=None, *, _param_mark=None)

argnames:参数名,以逗号分隔的字符串,表示一个或多个参数名称。或参数字符串组成的列表/元组。

        如果是一个参数,使用参数名的字符串。

        如果是多个参数,多个参数名之间使用逗号分隔的字符串,或者多个参数名组成的列表,或者多个参数名组成的元组。

argvalues:参数值,类型是一个可迭代对象,和参数名一一对应。

        如果argnames为一个参数,则argvalues是一个值列表。

        如果argnames为多个参数,则argvalues必须是一个嵌套元组的列表,其中每个元组元素值与参数名一一对应。

indirect:参数名称列表(参数名称的子集)或布尔值。

        indirect一般与Pytest的fixture,request.param组合使用

        当indrect =True时,argnames参数名是fixture夹具的函数名,argvalues则是给这个夹具函数传递的参数。

ids:标记参数化测试用例的执行名称,默认自动生成,多个参数名之间用"-"连接。

scope:参数范围。

1、单个参数名

新建 test_parametrize.py 文件如下:

import pytest


# 单个参数名
@pytest.mark.parametrize('a', [1, 2, 3])
def test_one(a):
    print(a)

运行命令:ytest test_parametrize.py -vs

(venv) C:Users57776PycharmProjectspytest-demotestmark>pytest test_parametrize.py -vs
==================================== test session starts ====================================
platform win32 -- Python 3.8.8, pytest-6.2.3, py-1.10.0, pluggy-0.13.1 -- e:programspythonpython38python.exe
cachedir: .pytest_cache
metadata: {'Python': '3.8.8', 'Platform': 'Windows-10-10.0.19041-SP0', 'Packages': {'pytest': '6.2.3', 'py': '1.10.0', 'pluggy': '0.13.1'}, 'Plugins': {'html': '3.1.1', 'metadata': '1.11.0', 'rerunfailures': '9.1.1', 'assume': '2.2.0', 'requests-mock': '1.7.0'}, 'JAVA_HOME': 'C:\Program Files\Java\jdk1.8.0_271'}
rootdir: C:Users57776PycharmProjectspytest-demotestmark, configfile: pytest.ini
plugins: html-3.1.1, metadata-1.11.0, rerunfailures-9.1.1, assume-2.2.0, requests-mock-1.7.0
collected 3 items                                                                                                                                                   

test_parametrize.py::test_one[1] 1                PASSED
test_parametrize.py::test_one[2] 2                PASSED
test_parametrize.py::test_one[3] 3                PASSED

==================================== 3 passed in 0.04s ====================================

(venv) C:Users57776PycharmProjectspytest-demotestmark>

说明:

argnames参数名只有一个参数的时候,使用参数名的字符串,argvalues参数值使用一个列表。

测试用例test_one使用装饰器parametrize,pytest每次运行测试用例的时候,参数名a都会从参数值[1,2,3]中取出一个值来运行子用例。

2、多个参数名

修改 test_parametrize.py 文件如下:

import pytest


# 单个参数名
@pytest.mark.parametrize('a', [1, 2, 3])
def test_one(a):
    print(a)


# 多个参数名
@pytest.mark.parametrize("a,b", [('a1', 'b1'), ('a2', 'b2'), ('a3', 'b3')])
# @pytest.mark.parametrize(['a', 'b'], [('a1', 'b1'), ('a2', 'b2'), ('a3', 'b3')])
# @pytest.mark.parametrize(('a', 'b'), [('a1', 'b1'), ('a2', 'b2'), ('a3', 'b3')])
def test_two(a, b):
    print(a, b)

运行命令:pytest test_parametrize.py -vs

(venv) C:Users57776PycharmProjectspytest-demotestmark>pytest test_parametrize.py -vs
=================================== test session starts ===================================
platform win32 -- Python 3.8.8, pytest-6.2.3, py-1.10.0, pluggy-0.13.1 -- e:programspythonpython38python.exe
cachedir: .pytest_cache
metadata: {'Python': '3.8.8', 'Platform': 'Windows-10-10.0.19041-SP0', 'Packages': {'pytest': '6.2.3', 'py': '1.10.0', 'pluggy': '0.13.1'}, 'Plugins': {'html': '3.1.1', 'metadata': '1.11.0', 'rerunfailures': '9.1.1', 'assume': '2.2.0', 'requests-mock': '1.7.0'}, 'JAVA_HOME': 'C:\Program Files\Java\jdk1.8.0_271'}
rootdir: C:Users57776PycharmProjectspytest-demotestmark, configfile: pytest.ini
plugins: html-3.1.1, metadata-1.11.0, rerunfailures-9.1.1, assume-2.2.0, requests-mock-1.7.0
collected 6 items                                                                                                                                                   

test_parametrize.py::test_one[1] 1                PASSED
test_parametrize.py::test_one[2] 2                PASSED
test_parametrize.py::test_one[3] 3                PASSED
test_parametrize.py::test_two[a1-b1] a1 b1                PASSED
test_parametrize.py::test_two[a2-b2] a2 b2                PASSED

test_parametrize.py::test_two[a3-b3] a3 b3                PASSED

=================================== 6 passed in 0.07s ===================================

(venv) C:Users57776PycharmProjectspytest-demotestmark>

说明:

argnames参数名有多个的时候,多个参数名之间使用逗号分隔的字符串,多个参数名组成的列表,多个参数名组成的元组,这三种写法都可以。

argnames参数名有多个的时候,argvalues必须是一个嵌套元组的列表,其中每个元组元素值与参数名一一对应。

ids参数,默认自动生成,多个参数名之间用"-"连接。

pytest运行的时候,parametrize装饰的测试用例test_two依次从参数值列表[('a1', 'b1'), ('a2', 'b2'), ('a3', 'b3')]中取出3个元组,运行3次测试用例。

3、indrect =True

修改 test_parametrize.py 文件如下:

import pytest
# 夹具参数化
@pytest.fixture()
def fixture_demo(request):
    return request.param + 1


lst = [1, 2, 3]


# indirect=True,argnames作为参数传入参数名对应的夹具函数
@pytest.mark.parametrize('fixture_demo', lst, indirect=True)
def test_three(fixture_demo):
    print(fixture_demo)

运行命令:pytest test_parametrize.py -vs


(venv) C:Users57776PycharmProjectspytest-demotestmark>pytest test_parametrize.py -vs
================================= test session starts =================================
platform win32 -- Python 3.8.8, pytest-6.2.3, py-1.10.0, pluggy-0.13.1 -- e:programspythonpython38python.exe
cachedir: .pytest_cache
metadata: {'Python': '3.8.8', 'Platform': 'Windows-10-10.0.19041-SP0', 'Packages': {'pytest': '6.2.3', 'py': '1.10.0', 'pluggy': '0.13.1'}, 'Plugins': {'html': '3.1.
1', 'metadata': '1.11.0', 'rerunfailures': '9.1.1', 'assume': '2.2.0', 'requests-mock': '1.7.0'}, 'JAVA_HOME': 'C:\Program Files\Java\jdk1.8.0_271'}
rootdir: C:Users57776PycharmProjectspytest-demotestmark, configfile: pytest.ini
plugins: html-3.1.1, metadata-1.11.0, rerunfailures-9.1.1, assume-2.2.0, requests-mock-1.7.0
collected 3 items                                                                                                                                                   

test_parametrize.py::test_three[1] 2                PASSED
test_parametrize.py::test_three[2] 3                PASSED
test_parametrize.py::test_three[3] 4                PASSED

=================================== 3 passed in 0.05s ===================================

(venv) C:Users57776PycharmProjectspytest-demotestmark>

说明:

当indrect =True时,argnames参数名是fixture夹具的函数名,argvalues则是给这个夹具函数传递值的参数。

夹具pytest.fixture(params) 可以用来实现参数化,参数化的时候这里需要用到一个参数request,用来接收fixture返回的结果,通过request.param来返回参数内容。

4、装饰测试类

修改 test_parametrize.py 文件如下:

import pytest 


# 装饰类需要注意参数要和类中的所有测试函数保持一致
@pytest.mark.parametrize("a,b", [('a1', 'b1'), ('a2', 'b2'), ('a3', 'b3')])
class TestClass:
    def test_four(self, a, b):
        print(a, b)

    def test_five(self, a, b):
        print(a + b)

运行命令:pytest test_parametrize.py -vs

(venv) C:Users57776PycharmProjectspytest-demotestmark>pytest test_parametrize.py -vs
=================================== test session starts ===================================
platform win32 -- Python 3.8.8, pytest-6.2.3, py-1.10.0, pluggy-0.13.1 -- e:programspythonpython38python.exe
cachedir: .pytest_cache
metadata: {'Python': '3.8.8', 'Platform': 'Windows-10-10.0.19041-SP0', 'Packages': {'pytest': '6.2.3', 'py': '1.10.0', 'pluggy': '0.13.1'}, 'Plugins': {'html': '3.1.
1', 'metadata': '1.11.0', 'rerunfailures': '9.1.1', 'assume': '2.2.0', 'requests-mock': '1.7.0'}, 'JAVA_HOME': 'C:\Program Files\Java\jdk1.8.0_271'}
rootdir: C:Users57776PycharmProjectspytest-demotestmark, configfile: pytest.ini
plugins: html-3.1.1, metadata-1.11.0, rerunfailures-9.1.1, assume-2.2.0, requests-mock-1.7.0
collected 6 items                                                                                                                                                   

test_parametrize.py::TestClass::test_four[a1-b1] a1 b1                PASSED
test_parametrize.py::TestClass::test_four[a2-b2] a2 b2                PASSED
test_parametrize.py::TestClass::test_four[a3-b3] a3 b3                PASSED
test_parametrize.py::TestClass::test_five[a1-b1] a1b1                PASSED
test_parametrize.py::TestClass::test_five[a2-b2] a2b2                PASSED
test_parametrize.py::TestClass::test_five[a3-b3] a3b3                PASSED

=================================== 6 passed in 0.20s ===================================

(venv) C:Users57776PycharmProjectspytest-demotestmark>

说明:

parametrize装饰的类TestClass中的所有测试用例都调用了参数化。

5、装饰模块

修改 test_parametrize.py 文件如下:

import pytest

pytestmark = pytest.mark.parametrize("a,b", [('a1', 'b1'), ('a2', 'b2'), ('a3', 'b3')])


def test_two(a, b):
    print(a, b)


class TestClass:
    def test_four(self, a, b):
        print(a, b)

    def test_five(self, a, b):
        print(a + b)

运行命令:pytest test_parametrize.py -vs

(venv) C:Users57776PycharmProjectspytest-demotestmark>pytest test_parametrize.py -vs
=================================== test session starts ===================================
platform win32 -- Python 3.8.8, pytest-6.2.3, py-1.10.0, pluggy-0.13.1 -- e:programspythonpython38python.exe
cachedir: .pytest_cache
metadata: {'Python': '3.8.8', 'Platform': 'Windows-10-10.0.19041-SP0', 'Packages': {'pytest': '6.2.3', 'py': '1.10.0', 'pluggy': '0.13.1'}, 'Plugins': {'html': '3.1.1', 'metadata': '1.11.0', 'rerunfailures': '9.1.1', 'assume': '2.2.0', 'requests-mock': '1.7.0'}, 'JAVA_HOME': 'C:\Program Files\Java\jdk1.8.0_271'}
rootdir: C:Users57776PycharmProjectspytest-demotestmark, configfile: pytest.ini
plugins: html-3.1.1, metadata-1.11.0, rerunfailures-9.1.1, assume-2.2.0, requests-mock-1.7.0
collected 9 items                                                                                                                                                   

test_parametrize.py::test_two[a1-b1] a1 b1                PASSED
test_parametrize.py::test_two[a2-b2] a2 b2                PASSED
test_parametrize.py::test_two[a3-b3] a3 b3                PASSED
test_parametrize.py::TestClass::test_four[a1-b1] a1 b1                PASSED
test_parametrize.py::TestClass::test_four[a2-b2] a2 b2                PASSED
test_parametrize.py::TestClass::test_four[a3-b3] a3 b3                PASSED
test_parametrize.py::TestClass::test_five[a1-b1] a1b1                PASSED
test_parametrize.py::TestClass::test_five[a2-b2] a2b2                PASSED
test_parametrize.py::TestClass::test_five[a3-b3] a3b3                PASSED

==================================== 9 passed in 0.08s ====================================

(venv) C:Users57776PycharmProjectspytest-demotestmark>

说明:

使用全局变量pytestmark = pytest.mark.parametrize(),可以参数化模块中的所有测试用例。

6、使用内置mark.xfail,在参数化中标记测试用例预期执行失败

修改 test_parametrize.py 文件如下:

import pytest 


# 使用内置mark.xfail,在参数化中标记单个测试用例预期执行失败
@pytest.mark.parametrize("test_input,expected",
                         [("3+5", 8), ("2+4", 6), pytest.param("6*9", 42, marks=pytest.mark.xfail)])
def test_eval(test_input, expected):
    assert eval(test_input) == expected

运行命令:pytest test_parametrize.py -vs

(venv) C:Users57776PycharmProjectspytest-demotestmark>pytest test_parametrize.py -v
================================== test session starts ==================================
platform win32 -- Python 3.8.8, pytest-6.2.3, py-1.10.0, pluggy-0.13.1 -- e:programspythonpython38python.exe
cachedir: .pytest_cache
metadata: {'Python': '3.8.8', 'Platform': 'Windows-10-10.0.19041-SP0', 'Packages': {'pytest': '6.2.3', 'py': '1.10.0', 'pluggy': '0.13.1'}, 'Plugins': {'html': '3.1.1', 'metadata': '1.11.0', 'rerunfailures': '9.1.1', 'assume': '2.2.0', 'requests-mock': '1.7.0'}, 'JAVA_HOME': 'C:\Program Files\Java\jdk1.8.0_271'}
rootdir: C:Users57776PycharmProjectspytest-demotestmark, configfile: pytest.ini
plugins: html-3.1.1, metadata-1.11.0, rerunfailures-9.1.1, assume-2.2.0, requests-mock-1.7.0
collected 3 items                                                                                                                                                   

test_parametrize.py::test_eval[3+5-8] PASSED                                                        [ 33%]
test_parametrize.py::test_eval[2+4-6] PASSED                                                          [ 66%]
test_parametrize.py::test_eval[6*9-42] XFAIL                                                                [100%]

=============================== 2 passed, 1 xfailed in 0.46s ===============================

(venv) C:Users57776PycharmProjectspytest-demotestmark>

说明:

xfail 标记的测试用例预期执行失败,实际执行失败,则状态标记为XFAIL。

7、堆叠多个parametrize装饰器

修改 test_parametrize.py 文件如下:

import pytest


# 堆叠多个parametrize装饰器,在这种情况下,每次调用都会参数化所有先前的参数化。
@pytest.mark.parametrize('a', ['a1', 'a2'])
@pytest.mark.parametrize('b', ['b1', 'b2', 'b3'])
def test_over(a, b):
    print(a, b)

运行命令:pytest test_parametrize.py -vs

(venv) C:Users57776PycharmProjectspytest-demotestmark>pytest test_parametrize.py -vs
=================================== test session starts ===================================
platform win32 -- Python 3.8.8, pytest-6.2.3, py-1.10.0, pluggy-0.13.1 -- e:programspythonpython38python.exe
cachedir: .pytest_cache
metadata: {'Python': '3.8.8', 'Platform': 'Windows-10-10.0.19041-SP0', 'Packages': {'pytest': '6.2.3', 'py': '1.10.0', 'pluggy': '0.13.1'}, 'Plugins': {'html': '3.1.1', 'metadata': '1.11.0', 'rerunfailures': '9.1.1', 'assume': '2.2.0', 'requests-mock': '1.7.0'}, 'JAVA_HOME': 'C:\Program Files\Java\jdk1.8.0_271'}
rootdir: C:Users57776PycharmProjectspytest-demotestmark, configfile: pytest.ini
plugins: html-3.1.1, metadata-1.11.0, rerunfailures-9.1.1, assume-2.2.0, requests-mock-1.7.0
collected 6 items                                                                                                                                                   

test_parametrize.py::test_over[b1-a1] a1 b1                PASSED
test_parametrize.py::test_over[b1-a2] a2 b1                PASSED
test_parametrize.py::test_over[b2-a1] a1 b2                PASSED
test_parametrize.py::test_over[b2-a2] a2 b2                PASSED
test_parametrize.py::test_over[b3-a1] a1 b3                PASSED
test_parametrize.py::test_over[b3-a2] a2 b3                PASSED

=================================== 6 passed in 0.07s ===================================

(venv) C:Users57776PycharmProjectspytest-demotestmark>

说明:

堆叠多个parametrize装饰器,在这种情况下,每次调用都会参数化所有先前的参数化。

二、pytest.fixture(params)

待整理


reference:

API Reference — pytest documentation

How to parametrize fixtures and test functions — pytest documentation

Parametrizing tests — pytest documentation

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1030814.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号