Pytest进阶之参数化

前言

unittest单元测试框架使用DDT进行数据驱动测试,那么身为功能更加强大且更加灵活的Pytest框架怎么可能没有数据驱动的概念呢?其实Pytest是使用@pytest.mark.parametrize装饰器来实现数据驱动测试的,那么今天我们就简单来说说在它是如何进行数据驱动测试的

单个参数

"""
------------------------------------
@Time : 2019/7/25 19:18
@Auth : linux超
@File : test_parametrize.py
@IDE  : PyCharm
@Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error!
@QQ   : [email protected]
@GROUP: 878565760
------------------------------------
"""
import pytest

data = [1, 2]

@pytest.mark.parametrize(‘a‘, data)
def test_parametrize(a):
    print(‘\n被加载测试数据为\n{}‘.format(a))

if __name__ == ‘__main__‘:
    pytest.main([‘-s‘])

输出

============================= test session starts =============================
platform win32 -- Python 3.7.2, pytest-4.3.1, py-1.8.0, pluggy-0.9.0
rootdir: E:\CnblogCode\pytest_parametrize, inifile:
plugins: rerunfailures-7.0, metadata-1.8.0, html-1.20.0
collected 2 items

test_parametrize.py
被加载测试数据为
1
.
被加载测试数据为
2
.

========================== 2 passed in 0.16 seconds ===========================

Process finished with exit code 0

说明

如果测试用例只需要一个参数时,我们存放数据的列表无序嵌套序列,@pytest.mark.parametrize(‘a‘, data)装饰器的第一个参数也只需要一个变量接收列表中的每个元素,第二个参数传递存储数据的列表,那么测试用例需要使用同名的字符串接收测试数据(实例中的a)且列表有多少个元素就会生成并执行多少个测试用例

一组数据

"""
------------------------------------
@Time : 2019/7/25 19:18
@Auth : linux超
@File : test_parametrize.py
@IDE  : PyCharm
@Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error!
@QQ   : [email protected]
@GROUP: 878565760
------------------------------------
"""
import pytest

data = [
    [1, 2, 3],
    [4, 5, 9]
]  # 列表嵌套列表
# data_tuple = [
#     (1, 2, 3),
#     (4, 5, 9)
# ]  # 列表嵌套元组

@pytest.mark.parametrize(‘a, b, expect‘, data)
def test_parametrize_1(a, b, expect):  # 一个参数接收一个数据
    print(‘\n测试数据为\n{},{},{}‘.format(a, b, expect))
    actual = a + b
    assert actual == expect

@pytest.mark.parametrize(‘value‘, data)
def test_parametrize_2(value):  # 一个参数接收一组数据
    print(‘\n测试数据为\n{}‘.format(value))
    actual = value[0] + value[1]
    assert actual == value[2]

if __name__ == ‘__main__‘:
    pytest.main([‘-s‘])

输出

============================= test session starts =============================
platform win32 -- Python 3.7.2, pytest-4.3.1, py-1.8.0, pluggy-0.9.0
rootdir: E:\CnblogCode\pytest_parametrize, inifile:
plugins: rerunfailures-7.0, metadata-1.8.0, html-1.20.0
collected 4 items

test_parametrize.py
测试数据为
1,2,3
.
测试数据为
4,5,9
.
测试数据为
[1, 2, 3]
.
测试数据为
[4, 5, 9]
.

========================== 4 passed in 0.17 seconds ===========================

Process finished with exit code 0

说明

当测试用例需要多个参数时,需要使用嵌套序列(嵌套元组&嵌套列表)的列表来存放测试数据

装饰器@pytest.mark.parametrize()可以使用单个变量接收数据,也可以使用多个变量接收,同样,测试用例函数也需要与其保持一致

当使用单个变量接收时,测试数据传递到测试函数内部时为列表中的每一个元素或者小列表,需要使用索引的方式取得每个数据

当使用多个变量接收数据时,那么每个变量分别接收小列表或元组中的每个元素

列表嵌套多少个多组小列表或元组,测生成多少条测试用例

图解对应关系

组合数据

"""
------------------------------------
@Time : 2019/7/25 19:18
@Auth : linux超
@File : test_parametrize.py
@IDE  : PyCharm
@Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error!
@QQ   : [email protected]
@GROUP: 878565760
------------------------------------
"""
import pytest

data_1 = [1, 2]
data_2 = [3, 4]  

@pytest.mark.parametrize(‘a‘, data_1)
@pytest.mark.parametrize(‘b‘, data_2)
def test_parametrize_1(a, b):
    print(‘\n测试数据为\n{},{}‘.format(a, b))

if __name__ == ‘__main__‘:
    pytest.main([‘-s‘])

输出

============================= test session starts =============================
platform win32 -- Python 3.7.2, pytest-4.3.1, py-1.8.0, pluggy-0.9.0
rootdir: E:\CnblogCode\pytest_parametrize, inifile:
plugins: rerunfailures-7.0, metadata-1.8.0, html-1.20.0
collected 4 items

test_parametrize.py
测试数据为
1,3
.
测试数据为
2,3
.
测试数据为
1,4
.
测试数据为
2,4
.

========================== 4 passed in 0.24 seconds ===========================

Process finished with exit code 0

说明

通过测试结果,我们发现执行了4条测试用例。不难分析原因是第一组数据的每个数据分别和第二组数据的每个数据结合的结果

标记用例

可以直接标记测试用例,参数化装饰器也可以识别(标记用例失败或跳过)

标记为无条件跳过(标记为失败为xfail,自己尝试)

"""
------------------------------------
@Time : 2019/7/25 19:18
@Auth : linux超
@File : test_parametrize.py
@IDE  : PyCharm
@Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error!
@QQ   : 2817404[email protected]
@GROUP: 878565760
------------------------------------
"""
import pytest

data_1 = [
    [1, 2, 3],
    pytest.param(3, 4, 8, marks=pytest.mark.skip)
]

def add(a, b):
    return a + b

@pytest.mark.parametrize(‘a, b, expect‘, data_1)
def test_parametrize_1(a, b, expect):
    print(‘\n测试数据为\n{},{}‘.format(a, b))
    assert add(a, b) == expect

if __name__ == ‘__main__‘:
    pytest.main([‘-vs‘])

输出

============================= test session starts =============================
platform win32 -- Python 3.7.2, pytest-4.3.1, py-1.8.0, pluggy-0.9.0 -- C:\Programs\Python\Python37-32\python.exe
cachedir: .pytest_cache
metadata: {‘Python‘: ‘3.7.2‘, ‘Platform‘: ‘Windows-7-6.1.7601-SP1‘, ‘Packages‘: {‘pytest‘: ‘4.3.1‘, ‘py‘: ‘1.8.0‘, ‘pluggy‘: ‘0.9.0‘}, ‘Plugins‘: {‘rerunfailures‘: ‘7.0‘, ‘metadata‘: ‘1.8.0‘, ‘html‘: ‘1.20.0‘}, ‘JAVA_HOME‘: ‘D:\\JDK‘}
rootdir: E:\CnblogCode\pytest_parametrize, inifile:
plugins: rerunfailures-7.0, metadata-1.8.0, html-1.20.0
collecting ... collected 2 items

test_parametrize.py::test_parametrize_1[1-2-3]
测试数据为
1,2
PASSED
test_parametrize.py::test_parametrize_1[3-4-8] SKIPPED

===================== 1 passed, 1 skipped in 0.17 seconds =====================

Process finished with exit code 0

说明

输出结果显示收集到2个用例,一个通过,一个被跳过,当我们不想执行某组测试数据时,我们可以标记skip或skipif;当我们预期某组数据会执行失败时,我们可以标记为xfail等

总结

Pytest中实现数据驱动就是如此了

需要注意几点

1. 装饰器的第一个参数是一个列表形式的字符串参数"a, b, c" 不能写成"a", "b", "c"

2.测试数据需存储在序列类型的变量中,当然也可以使用序列嵌套字典类型

补充实例

"""
------------------------------------
@Time : 2019/7/25 19:18
@Auth : linux超
@File : test_parametrize.py
@IDE  : PyCharm
@Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error!
@QQ   : [email protected]
@GROUP: 878565760
------------------------------------
"""
import pytest

data_1 = (
    {
        ‘user‘: 1,
        ‘pwd‘: 2
     },
    {
        ‘user‘: 3,
        ‘pwd‘: 4
    }
)

@pytest.mark.parametrize(‘dic‘, data_1)
def test_parametrize_1(dic):
    print(‘\n测试数据为\n{}‘.format(dic))

if __name__ == ‘__main__‘:
    pytest.main([‘-s‘])

输出

============================= test session starts =============================
platform win32 -- Python 3.7.2, pytest-4.3.1, py-1.8.0, pluggy-0.9.0
rootdir: E:\CnblogCode\pytest_parametrize, inifile:
plugins: rerunfailures-7.0, metadata-1.8.0, html-1.20.0
collected 2 items

test_parametrize.py
测试数据为
{‘user‘: 1, ‘pwd‘: 2}
.
测试数据为
{‘user‘: 3, ‘pwd‘: 4}
.

========================== 2 passed in 0.20 seconds ===========================

Process finished with exit code 0

原文地址:https://www.cnblogs.com/linuxchao/p/linuxchao-pytest-parametrize.html

时间: 2024-08-01 19:10:51

Pytest进阶之参数化的相关文章

pytest进阶之html测试报告

前言 Pytest系列已经写了几篇文章了,也不知道对多少人有帮助,总之对于我自己来说该掌握的都已经掌握了,那么今天我们再来说说pytest如何生成一个完整的html测试报告,让你在吹牛逼的路上再多一份资本!废话不多说,进入正题!(咋就莫名其妙想起这句话了呢, 估计看文章看多了,貌似挺多人用这句话过度……) 使用pytest-html插件生成测试报告 pytest-html生成报告 pytest是借助pytest-html插件生成测试测试报告, 不用自己编写生成报告代码.github源码地址 ht

pytest进阶之配置文件

前言 pytest配置文件能够改变pytest框架代码的运行规则.比如修改pytest收集用例的规则,添加命令行参数等等!下面我们来一一讲解常用的一些配置项 Help 通过命令pytest --help查看配置文件中可以添加的一些参数及选项,这些选项都是可以添加到pytest的配置文件的 [pytest] ini-options in the first pytest.ini|tox.ini|setup.cfg file found: markers (linelist) markers for

pytest.mark.parametrize()参数化的应用一

1 from page.LoginPage import Loginpage 2 import os, sys, pytest 3 4 base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 5 sys.path.append(base_dir) 6 7 8 class TestLogin(): 9 10 @pytest.mark.parametrize( 11 "name, password", 1

Python 进阶之源码分析:如何将一个类方法变为多个方法?

前一篇文章<Python 中如何实现参数化测试?>中,我提到了在 Python 中实现参数化测试的几个库,并留下一个问题: 它们是如何做到把一个方法变成多个方法,并且将每个方法与相应的参数绑定起来的呢? 我们再提炼一下,原问题等于是:在一个类中,如何使用装饰器把一个类方法变成多个类方法(或者产生类似的效果)? # 带有一个方法的测试类 class TestClass: def test_func(self): pass # 使用装饰器,生成多个类方法 class TestClass: def

Allure-pytest功能特性介绍

前言 Allure框架是一个灵活的轻量级多语言测试报告工具,它不仅以web的方式展示了简介的测试结果,而且允许参与开发过程的每个人从日常执行的测试中最大限度的提取有用信息从dev/qa的角度来看,Allure报告简化了常见缺陷的统计:失败的测试可以分为bug和被中断的测试,还可以配置日志.步骤.fixture.附件.计时.执行历史以及与TMS和BUG管理系统集成,所以,通过以上配置,所有负责的开发人员和测试人员可以尽可能的掌握测试信息.从管理者的角度来看,Allure提供了一个清晰的“大图”,其

Jmeter进阶学习二(参数化)

1.疑问:为啥要使用参数化? 在测试过程中,参数化也是一种很重要的东西,比如:如果系统过程中多次使用同一个id,万一此id发生变化了,就需要每个文件中id一个一个的进行修改,如果使用参数化的话,就只需修改一个文件即可: 这样的话可以减少工作量: 2.此处采用的是用户定义的变量: 3.如何调用定义的变量? ...... 未完待续.... Jmeter进阶学习二(参数化)

pytest 8 参数化parametrize

pytest.mark.parametrize装饰器可以实现用例参数化 1.以下是一个实现检查一定的输入和期望输出测试功能的典型例子 import pytest @pytest.mark.parametrize("test_input,expected",[("3+5",8),("2+4",6),("6*9",42)]) def test_add(test_input,expected): assert eval(test_i

pytest.10.使用fixture参数化测试预期结果

From: http://www.testclass.net/pytest/test_api_with_expected_result/ 背景 接上一节v2ex网站的查看论坛节点信息的api. 我们在上一节的测试用例里只断言了返回值的name字段必须与我们传入的入参相同,但是返回值的id却没有进行判定.这一节里我们加强一下测试脚本,实现判断id的功能. 测试数据 python, id=90 java, id=63 nodejs, id=436 go, id=375 代码实现 在v2ex_api_

性能测试十二:jmeter进阶之java请求参数化

如项目中的ip.端口号之类的,都可以在此代码中定义 public Arguments getDefaultParameters() { // TODO Auto-generated method stub return null; } 此处注册两个参数到jmeter的变量池: p_name,默认值设为abc p_desc,默认值设为123 /** * 此函数里面可以人工注册一些参数,这些参数可以在java请求面板里展示或更改 */ @Override public Arguments getDe