项目目录

在这里插入图片描述

一.Pytest使用@pytest.mark.parametrize装饰器来实现数据驱动测试

二.装饰测试类

test_parametrize_class.py

# Pytest是使用@pytest.mark.parametrize装饰器来实现数据驱动测试
# 当装饰器装饰测试类时,给数据集合会被传递给给类的所有方法。
import pytest


data_one = [
    (1, 2, 3),
    (4, 5, 9)
]


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


# 装饰测试类:当装饰器装饰测试类时,获取的数据集合数据,会被传递给类中的所有方法
@pytest.mark.parametrize('a, b, expect', data_one)
class TestParametrize(object):

    def test_parametrize_one(self, a, b, expect):
        print(u'测试函数1测试数据为{}-{}'.format(a, b))
        assert add(a, b) == expect

    def test_parametrize_two(self, a, b, expect):
        print(u'测试函数2数据为{}-{}'.format(a, b))
        assert add(a, b) == expect


if __name__ == '__main__':
    pytest.main(['-sv'])

在这里插入图片描述

三.装饰测试函数

1.单个数据

test_parametrize_function_one.py

# 装饰测试函数:单个数据
import pytest

data = [1, 2]

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


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


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

在这里插入图片描述

2.一组数据

test_parametrize_function_two.py

# 装饰测试函数:一组数据
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_one(a, b, expect):           # 一个参数接收一个数据
    print(u'测试数据为{},{},{}'.format(a, b, expect))
    actual = a + b
    assert actual == expect


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


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

在这里插入图片描述

3.说明

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

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

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

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

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

3.6.图解对应关系

在这里插入图片描述

4.组合数据

test_parametrize_function_three.py

# 装饰测试函数:组合数据
import pytest

data_one = [1, 2]
data_two = [3, 4]


@pytest.mark.parametrize('a', data_one)
@pytest.mark.parametrize('b', data_two)
def test_parametrize_one(a, b):
    print(u'测试数据为{},{}'.format(a, b))


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

# 一个测试函数还可以同时被多个参数化装饰器装饰,那么多个装饰器中的数据会进行交叉组合的方式传递给测试函数,进而生成n*n个测试用例。

在这里插入图片描述

5.标记用例

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

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

test_parametrize_function_four.py

import pytest

data_one = [
    [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_one)
def test_parametrize_1(a, b, expect):
    print(u'测试数据为{},{}'.format(a, b))
    assert add(a, b) == expect


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


# 此时一个通过,一个被跳过,当不想执行某组测试数据时,我们可以标记skip或skipif;当预期某组数据会执行失败时,我们可以标记为xfail等

在这里插入图片描述

6.嵌套字典

test_parametrize_function_five.py

import pytest

data_one = (
    {
        'user': 1,
        'pwd': 2
     },
    {
        'user': 3,
        'pwd': 4
    }
)


@pytest.mark.parametrize('dic', data_one)
def test_parametrize_1(dic):
    print(u'测试数据为{}'.format(dic))


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

在这里插入图片描述

四.增加可读性:使用ids参数

test_parametrize_ids_one.py

#增加可读性:使用ids参数
import pytest

data_one = [
    (1, 2, 3),
    (4, 5, 9)
]


#1.参数化装饰器有参数ids,可以标识每一个测试用例,自定义测试数据结果的显示,可以标记测试用例使用的测试数据是什么。
#2.ids参数应该是一个字符串列表,必须和数据对象列表的长度保持一致。
ids = ["a:{} + b:{} = expect:{}".format(a, b, expect) for a, b, expect in data_one]

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


@pytest.mark.parametrize('a, b, expect', data_one, ids=ids)
class TestParametrize(object):

    def test_parametrize_one(self, a, b, expect):
        print(u'测试函数1测试数据为{}-{}'.format(a, b))
        assert add(a, b) == expect

    def test_parametrize_two(self, a, b, expect):
        print(u'测试函数2测试数据为{}-{}'.format(a, b))
        assert add(a, b) == expect


if __name__ == '__main__':
    pytest.main(['-v'])

在这里插入图片描述

1.自定义id做标识

1.1.除了使用ids参数增加输出可读性外,还可以在参数列表的参数旁边定义一个id值来做标识

test_parametrize_ids_two.py

# 增加可读性:使用ids参数(自定义id做标识)
import pytest

data_one = [
    pytest.param(1, 2, 3, id="(a+b):pass"),         # id的值可以自定义
    pytest.param(4, 5, 10, id="(a+b):fail")
]


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


class TestParametrize(object):
    @pytest.mark.parametrize('a, b, expect', data_one)
    def test_parametrize_one(self, a, b, expect):
        assert add(a, b) == expect


if __name__ == '__main__':
    pytest.main(['-v'])

# 如果使用此方法来标记测试用例,一定要严格按照格式来使用,语法为pytest.param(value, id='somthing')

在这里插入图片描述

五.总结

1.Pytest中实现数据驱动就是使用@pytest.mark.parametrize装饰器来实现数据驱动

2.装饰器与测试用例使用单个变量接收多组数据与多个变量接收多个数据的访问方法

3.不同测试数据形式(列表嵌套元组,列表,字典等)时,如何传递数据及访问数据

4.装饰器装饰测试类和测试函数的不同之处:装饰测试类时,类内所有的方法必须接送测试数据,否则会报错,装饰测试函数时比较灵活,如果函数不使用数据就可以不装饰

5.选择使用ids参数,可以输出结果的可读性,与测试数据中定义id参数值来标识测试用例

六.注意

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

2.ids是个字符串列表,长度需要与测试数据列表的长度一致
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐