pytest参数化详解

发布于:2022-11-09 ⋅ 阅读:(17) ⋅ 点赞:(0) ⋅ 评论:(0)

在这里插入图片描述


一.概念

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

可以使用 @pytest.mark.parametrize(argnames, argvalues) 装饰器达到批量传送参数的目的

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

parametrize()的第一个参数是用逗号分割的字符串列表,第二个参数是一个值列表

二.单个参数

test_params

import pytest

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

class TestParams:

    @pytest.mark.parametrize('a',[1,2,3,4,5])
    def test_par1(self,a):
        assert add(a,1)==a+1

命令行执行:

pytest

在这里插入图片描述
特别注意:
@pytest.mark.parametrize() 装饰器接收两个参数,
第一个参数是以字符串的形式标识用例函数的参数,
第二个参数以列表或元组的形式传递测试数据。
在这里插入图片描述

三.多个参数

案例1

test_params

import pytest

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

class TestParams:

    @pytest.mark.parametrize('a,b,c',[[1,2,3],[3,4,5],[1,3,4],[2,5,7]])
    def test_par1(self,a,b,c):
        assert add(a,b)==c

执行命令
在这里插入图片描述
特别注意:
多个参数之间要用逗号分隔
参数名称和个数要一一对应

在这里插入图片描述

案例2:使用py文件存放测试数据

测试数据

login_data_list = [
    	{'username': 'kobe', 'password': 666666, 'expect': '登录成功'},
    	{'username': 'kobe', 'password': 111111, 'expect': '用户名或者密码错误'},
    	{'username': '', 'password': 666666, 'expect': ''},
	]

test_work

import pytest
from data.data1 import login_data_list

class TestParams:

    @pytest.mark.parametrize('test_data',login_data_list)
    def test_par1(self,test_data):
        username=test_data['username']
        password=test_data['password']
        assert username=='kobe' and password==666666

测试结果
在这里插入图片描述

案例3:使用yaml文件存放测试数据

在这里插入图片描述

yaml文件

-
  name: '账号密码正确'
  username: 'kobe'
  password: 666666

-
  name: '用户名为空'
  username:
  password: 666666

-
  name: '用户名或者密码错误'
  username: 'james'
  password: 666666

read_yaml.py

import os
import yaml

def read_yaml(yaml_file_path):
    try:
        with open( yaml_file_path, "r",encoding="utf-8") as f:
            value = yaml.load(stream=f, Loader=yaml.FullLoader)
    except:
        with open(yaml_file_path, "r",encoding="gbk") as f:
            value = yaml.load(stream=f, Loader=yaml.FullLoader)
    print(value)
    return value



if __name__ == '__main__':
    read_yaml(r'D:\project_development\api_pytest\data\test_yaml.yaml')

读取结果:

[{'name': '账号密码正确', 'username': 'kobe', 'password': 666666}, {'name': '用户名为空', 'username': None, 'password': 666666}, {'name': '用户名或者密码错误', 'username': 'james', 'password': 666666}]

test_yaml_work.py

import pytest
from utils.read_yaml import read_yaml

class TestParams:

    @pytest.mark.parametrize('case',read_yaml(r'D:\project_development\api_pytest\data\test_yaml.yaml'))
    def test_login(self,case):
        username=case['username']
        password=case['password']
        assert username=='kobe' and password==666666

执行测试:

D:\project_development\api_pytest>pytest testcases/params/test_yaml_work.py

在这里插入图片描述

案例4:使用json文件存放测试数据

在这里插入图片描述

test_json.json


[
  {
    "name": "账号密码正确",
    "username": "kobe",
    "password": 666666
  },
  {
    "name": "用户名为空",
    "username": "",
    "password": 666666
  },
  {
    "name": "用户名或者密码错误",
    "username": "james",
    "password": 666666
  }
]

read_json.py

import os
import json

def read_json(json_file_path):
    try:
        with open(json_file_path, "r", encoding="utf-8") as f:
            datas = json.load(f)
    except:
        with open(json_file_path, "r", encoding="gbk") as f:
            datas = json.load(f)
    if not isinstance(datas, list):
        raise ValueError('json文件内的用例数据格式不符护规范')

    print(datas)
    return datas


if __name__ == '__main__':
    read_json(r'D:\project_development\api_pytest\data\test_json.json')

读取结果:

[{'name': '账号密码正确', 'username': 'kobe', 'password': 666666}, {'name': '用户名为空', 'username': '', 'password': 666666}, {'name': '用户名或者密码错误', 'username': 'james', 'password': 666666}]

test_json_work.py

import pytest
from utils.read_yaml import read_yaml

class TestParams:

    @pytest.mark.parametrize('case',read_yaml(r'D:\project_development\api_pytest\data\test_yaml.yaml'))
    def test_login(self,case):
        username=case['username']
        password=case['password']
        assert username=='kobe' and password==666666


四.对测试类参数化

测试类的参数化,其实际上也是对类中的测试方法进行参数化。类中的测试方法的参数必须与@pytest.mark.parametrize()中的标识的参数个数一致。

在这里插入图片描述

案例1

import pytest

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


@pytest.mark.parametrize('a,b,c',[[1,2,3],[1,3,4],[2,5,7]])
class TestParams:

    def test_par1(self,a,b,c):
        assert add(a,b)==c

    def test_par2(self,a,b,c):
        assert add(a,b)==c

执行结果

在这里插入图片描述


在这里插入图片描述