• pytest合集(7)— 参数化/数据驱动


    一、pytest.mark.parametrize()

    语法糖:

    parametrize(argnamesargvaluesindirect=Falseids=Nonescope=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:\Users\057776\PycharmProjects\pytest-demo\testmark>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:\programs\python\python38\python.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:\Users\057776\PycharmProjects\pytest-demo\testmark, 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:\Users\057776\PycharmProjects\pytest-demo\testmark>

    说明:

    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:\Users\057776\PycharmProjects\pytest-demo\testmark>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:\programs\python\python38\python.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:\Users\057776\PycharmProjects\pytest-demo\testmark, 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:\Users\057776\PycharmProjects\pytest-demo\testmark>

    说明:

    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:\Users\057776\PycharmProjects\pytest-demo\testmark>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:\programs\python\python38\python.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:\Users\057776\PycharmProjects\pytest-demo\testmark, 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:\Users\057776\PycharmProjects\pytest-demo\testmark>

    说明:

    当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:\Users\057776\PycharmProjects\pytest-demo\testmark>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:\programs\python\python38\python.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:\Users\057776\PycharmProjects\pytest-demo\testmark, 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:\Users\057776\PycharmProjects\pytest-demo\testmark>

    说明:

    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:\Users\057776\PycharmProjects\pytest-demo\testmark>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:\programs\python\python38\python.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:\Users\057776\PycharmProjects\pytest-demo\testmark, 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:\Users\057776\PycharmProjects\pytest-demo\testmark>

    说明:

    使用全局变量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:\Users\057776\PycharmProjects\pytest-demo\testmark>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:\programs\python\python38\python.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:\Users\057776\PycharmProjects\pytest-demo\testmark, 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:\Users\057776\PycharmProjects\pytest-demo\testmark>

    说明:

    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:\Users\057776\PycharmProjects\pytest-demo\testmark>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:\programs\python\python38\python.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:\Users\057776\PycharmProjects\pytest-demo\testmark, 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:\Users\057776\PycharmProjects\pytest-demo\testmark>

    说明:

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

    二、pytest.fixture(params)

    待整理


    reference:

    API Reference — pytest documentation

    How to parametrize fixtures and test functions — pytest documentation

    Parametrizing tests — pytest documentation

  • 相关阅读:
    source insight & keil 中文乱码
    关于MATLAB R2022b中MATLAB function没有edit data选项的解决办法
    ELTEK电源维修SMPS5000SIL整流器模块故障分析及特点
    Kconfig 和 Kbuild
    RK3399驱动开发 | 09 - 基于RK808 PMIC的电源管理驱动
    水墨屏RFID超高频标签|RFID电子纸之组态软件操作说明2
    算法-位运算-数字范围按位与
    嵌入式分享合集87
    php mysql运动器材租赁预约管理系统
    linux静态库与动态库
  • 原文地址:https://blog.csdn.net/panc_guizaijianchi/article/details/126018993