python自动化框架pytest(三)--数据驱动(参数化)

参数化,就是把测试过程中的数据提取出来,通过参数传递不同的数据来驱动用例运行。其实也就是数据驱动的概念。

在 Unittest 中,我们讲过使用 ddt 库配合 unittest 实现数据驱动。在 Pytest 中并不需要额外的库,通过 pytest.mark.parametrize()即可实现参数化。

方法:
     parametrize(argnames, argvalues, indirect=False, ids=None, scope=None)
 常用参数:
     argnames:参数名
     argvalues:参数对应值,类型必须为list或元组
                当参数为一个时格式:[value]
                当参数个数大于一个时,格式为:[(param_value1,param_value2.....),(param_value1,param_value2.....)]
      ids:使用的数据组别名,类型必须为list或元组,与argvalues一一对应,用于使用的数据组的展示
 使用方法:
     @pytest.mark.parametrize(argnames,argvalues)
     ️ 参数值为N个,测试方法就会运行N次

单个参数

在使用pytest.mark.parametrize()传递参数化数据时,测试用例本身必须有参数。
测试用例的参数名必须要跟parametrize传递的参数名保持一致

import pytest

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

# 单个参数的情况
@pytest.mark.parametrize('a', (1,2,3,4))
def test_add(a):  # => 作为用例参数,接收装饰器传入的数据
    print('\na的值:', a)
    assert add(a, 1) == a+1

if __name__ == '__main__':
    pytest.main(["-s", "demo.py"])

输出结果:

collected 4 items

demo.py 
a的值: 1
.
a的值: 2
.
a的值: 3
.
a的值: 4
.

============================== 4 passed in 0.06s ==============================

注意用法,@pytest.mark.parametrize() 装饰器接收两个参数,一个参数是以字符串的形式标识用例函数的参数,第二个参数以列表或元组的形式传递测试数据。


image.png

多个参数

多个参数,@pytest.mark.parametrize()第一个参数依然是字符串, 对应用例的多个参数用逗号分隔。第二个参数为一个二维的列表或者元组

import pytest

# 待测函数
def add(a, b):
    return a + b

# 多个参数的情况
@pytest.mark.parametrize('a,b,c', ([1,2,3],[4,5,9],[7,8,15]))
def test_add(a,b,c):  # => 作为用例参数,接收装饰器传入的数据
    print('\na,b,c的值分别为:', f"{a},{b},{c}")
    assert add(a, b) == c

if __name__ == '__main__':
    pytest.main(["-s", "demo.py","-v"])

执行后输出:

collecting ... collected 3 items

demo.py::test_add[1-2-3] 
a,b,c的值分别为: 1,2,3
PASSED
demo.py::test_add[4-5-9] 
a,b,c的值分别为: 4,5,9
PASSED
demo.py::test_add[7-8-15] 
a,b,c的值分别为: 7,8,15
PASSED

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

对测试类参数化

以上例子我们是对单个的测试用例进行了数据驱动,如果要对整个测试类操作,其实际上也是对类中的测试方法进行参数化。类中的测试方法的参数必须与@pytest.mark.parametrize()中的标识的参数个数一致且参数名相同。
每个测试用例都会循环执行传入参数的组数的次数

import pytest

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

@pytest.mark.parametrize('a, b, c', ([1,2,3],[4,13,9],[7,8,15]))
class TestAbc():
    def test_add1(self,a,b,c):  # => 作为用例参数,接收装饰器传入的数据
        assert add(a, b) == c
    def test_add2(self,a,b,c):  # => 作为用例参数,接收装饰器传入的数据
        assert add(a, c) == b
    def test_other(self,a,b,c):
        print("\na,b的值分别为:",f"{a},{b}")

if __name__ == '__main__':
    pytest.main(["-s", "demo.py","-v"])

修改结果显示名称

通过上面的运行结果,我们可以看到,为了区分参数化的运行结果,在结果中都会显示数据组合而成的名称。

数据短小还好说,如果数据比较长而复杂的话,那么就会很难看。

@pytest.mark.parametrize() 还提供了第三个 ids 参数来自定义显示结果,数据格式为元组或者列表,与传入的第二个参数一一对应,仅作展示所用。

test_add[1-2-3]这是结果中显示的名称,ids 的修改会作用于[]中的显示。

我们下面的示例简单的为数据编了一个号:

import pytest

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

# ids 的作用
data = ([1,2,3],[4,13,9],[7,8,15])
ids = [f'data{d}' for d in range(len(data))] # => 生成与数据数量相同的名称列表
# ids = ('data0','data1','data2')
@pytest.mark.parametrize('a, b, c', data, ids=ids)
def test_add1(a,b,c):
    assert add(a, b) == c


if __name__ == '__main__':
    pytest.main(["-s", "demo.py","-v"])

输出结果:

demo.py::test_add1[data0] PASSED
demo.py::test_add1[data1] FAILED
demo.py::test_add1[data2] PASSED

================================== FAILURES ===================================

常用的测试用例管理方式

在进行自动化测试的时候,一般需要对数据进行一个统筹规划实现以用例数据驱动框架进行测试。
常见的有

excel存放
优点: 便于维护,框架成型之后维护用例的人员没有学习成本。
缺点: 执行效率低,且用例量级大的时候易卡顿。

yaml存放
优点: 便于维护,轻便
缺点: 学习成本,用例编写设置不够直观

json存放
优点: 便于维护,轻便
缺点: 学习成本,用例编写设置不够直观

类属性存放
优点: 调用便利
缺点: 学习成本

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269