pytest:参数化用例

一、如果待测试的输入和输出是一组数据,可以把测试数据组织起来用不同的测试数据调用相同的测试方法。参数化顾名思义就是把不同的参数,写到一个集合里,然后程序会自动取值运行用例,直到集合为空便结束。pytest中可以使用@pytest.mark.parametrize来参数化。

使用parametrize实现参数化

parametrize()方法源码:

def  parametrize(self,argnames,argvalues,indirect=False,ids=None,scope=None)

主要参数说明

----argsnames:参数名 是个字符串如中间用逗号分隔则表示为多个参数名

----argvalues:参数值  参数组成的列表 列表中的几个元素就会生成几条用例

 

使用方法:

---使用 @pytest.mark.paramtrize()装饰器测试方法

----parametrize('data',param)中的 data是自定义的参数名,param是引入的参数列表

----将自定义的参数名data作为参数传给测试用例test_func

---然后就可以在测试用例内部使用data的参数了

 

创建测试用例,传入三组参数,每组两个元素,判断每组参数里面表达式和值是否相等代码如下:

#!/usr/bin/env python
# _*_coding: utf-8 _*_

import pytest


@pytest.mark.parametrize("test_input,expected", [("3+5", 8), ("2 + 5", 7), ("7 * 5", 30)])
def test_eval(test_input, expected):
    assert eval(test_input) == expected

运行结果:

Testing started at 15:17 ...
C:\Python\python.exe "C:\Program Files\JetBrains\PyCharm Community Edition 2019.1\helpers\pycharm\_jb_pytest_runner.py" --target test_parametrize1.py::test_eval
Launching pytest with arguments test_parametrize1.py::test_eval in C:\Users\wanwen\PycharmProjects\vigo\xuexi\20210123
============================= test session starts =============================
platform win32 -- Python 3.8.0, pytest-5.4.3, py-1.9.0, pluggy-0.13.1
rootdir: C:\Users\wanwen\PycharmProjects\vigo\xuexi\20210123
plugins: html-2.1.1, metadata-1.11.0, ordering-0.6collected 3 items

test_parametrize1.py ..F
test_parametrize1.py:6 (test_eval[7 * 5-30])
35 != 30

Expected :30
Actual   :35
<Click to see difference>

test_input = '7 * 5', expected = 30

    @pytest.mark.parametrize("test_input,expected", [("3+5", 8), ("2 + 5", 7), ("7 * 5", 30)])
    def test_eval(test_input, expected):
>       assert eval(test_input) == expected
E       AssertionError: assert 35 == 30
E        +  where 35 = eval('7 * 5')

test_parametrize1.py:9: AssertionError

Assertion failed
                                                 [100%]

================================== FAILURES ===================================
_____________________________ test_eval[7 * 5-30] _____________________________

test_input = '7 * 5', expected = 30

    @pytest.mark.parametrize("test_input,expected", [("3+5", 8), ("2 + 5", 7), ("7 * 5", 30)])
    def test_eval(test_input, expected):
>       assert eval(test_input) == expected
E       AssertionError: assert 35 == 30
E        +  where 35 = eval('7 * 5')

test_parametrize1.py:9: AssertionError
=========================== short test summary info ===========================
FAILED test_parametrize1.py::test_eval[7 * 5-30] - AssertionError: assert 35 ...
========================= 1 failed, 2 passed in 0.12s =========================

Process finished with exit code 0

Assertion failed

Assertion failed

整个执行过程中,pytest将参数列表

[("3+5", 8), ("2 + 5", 7), ("7 * 5", 30)]中的三组数据取出来,每组数据生成一条测试用例,并且将每组数据中的两个元素分别赋值到方法中,
作为测试方法的参数有测试用例使用

二、多次使用parametrize
同一个测试用例还可以同时添加多个@pytest.mark.parametrize装饰器,多个
parametrize的所有元素互相组合(类似笛卡尔积)生成大量的测试用例
场景:比如登入场景,用户输入情况有n种,密码的输入情况有M种希望验证用户名和密码就会涉及到n*m种组合的测试用例,
如果把这些数据一一列出来工作量也是非常大的。pytest提供了一种参数化方式
将多组测试数据组合生成大量的测试用例
实例代码如下:
#!/usr/bin/env python
# _*_coding: utf-8 _*_
import pytest


@pytest.mark.parametrize("x", [1, 2])
@pytest.mark.parametrize("y", [8, 10, 11])
def test_foo(x, y):
    print(f"测试数据组合x:{x},y:{y}")

运行结果:

Testing started at 15:31 ...
C:\Python\python.exe "C:\Program Files\JetBrains\PyCharm Community Edition 2019.1\helpers\pycharm\_jb_pytest_runner.py" --target test_parametrize2.py::test_foo
Launching pytest with arguments test_parametrize2.py::test_foo in C:\Users\wanwen\PycharmProjects\vigo\xuexi\20210123
============================= test session starts =============================
platform win32 -- Python 3.8.0, pytest-5.4.3, py-1.9.0, pluggy-0.13.1
rootdir: C:\Users\wanwen\PycharmProjects\vigo\xuexi\20210123
plugins: html-2.1.1, metadata-1.11.0, ordering-0.6collected 6 items

test_parametrize2.py                                               [100%]

============================== 6 passed in 0.04s ==============================

Process finished with exit code 0
.测试数据组合x:1,y:8
.测试数据组合x:2,y:8
.测试数据组合x:1,y:10
.测试数据组合x:2,y:10
.测试数据组合x:1,y:11
.测试数据组合x:2,y:11

分析如上运行结果,测试方法test_foo()添加了两个@pytest.mark.parametrize()装饰器,两个装饰器分别提供两个参数值得列表,2*3=6种结合,pytest便会生成6条

测试用例。在测试中使用这种参数自由组合,可以实现全面测.

 

三、@pytest.fixture 与 @pytest.mark.parametrize结合实现参数化

parametrize源码:

def  parametrize(self,argnames,argvalues,indirect=False,ids=None,scope=None):

indirect参数设置为true,pytest会把argnames当做函数去执行,将argvalues作为参数传入到argnames这个函数里

实例代码如下:

#!/usr/bin/env python
# _*_coding: utf-8 _*_
import pytest

test_user_data = ['Tome', 'Jerry']


@pytest.fixture(scope="module")
def login_r(request):
    user = request.param
    print(f"\n 登入用户:{user}")
    return user


@pytest.mark.parametrize("login_r", test_user_data, indirect=True)
def test_login(login_r):
    a = login_r
    print(f"测试用例中login的返回值:{a}")
    assert a != ""

运行结果如下:

Testing started at 15:53 ...
C:\Python\python.exe "C:\Program Files\JetBrains\PyCharm Community Edition 2019.1\helpers\pycharm\_jb_pytest_runner.py" --path C:/Users/wanwen/PycharmProjects/vigo/xuexi/20210123/test_parametrize3.py
Launching pytest with arguments C:/Users/wanwen/PycharmProjects/vigo/xuexi/20210123/test_parametrize3.py in C:\Users\wanwen\PycharmProjects\vigo\xuexi\20210123
============================= test session starts =============================
platform win32 -- Python 3.8.0, pytest-5.4.3, py-1.9.0, pluggy-0.13.1
rootdir: C:\Users\wanwen\PycharmProjects\vigo\xuexi\20210123
plugins: html-2.1.1, metadata-1.11.0, ordering-0.6collected 2 items

test_parametrize3.py                                                   [100%]

============================== 2 passed in 0.03s ==============================

Process finished with exit code 0

上面的结果可以看出,当indirect=True时,会将login_r作为参数,test_user_data被当作参数传入到login_r方法中生成多条测试用例,通过return将结果返回,当调用login_r可以获取到login_r这个方法的返回数据。


posted @ 2021-01-28 15:53  剑尊  阅读(163)  评论(0编辑  收藏  举报