• pytest参数化详解


    在这里插入图片描述


    一.概念

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

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

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

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

    pytest有三种传参方式:

    @pytest.mark.parametrize() 通过装饰器方式进行参数化(最常使用)
    pytest.fixture()方式进行参数化,fixture装饰的函数可以作为参数传入其他函数
    conftest.py文件中存放参数化函数,可作用于模块内的所有测试用例

    二.单个参数

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    命令行执行:

    pytest
    
    • 1

    在这里插入图片描述
    特别注意:
    @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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

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

    在这里插入图片描述

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

    测试数据

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

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

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

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

    在这里插入图片描述

    yaml文件

    -
      name: '账号密码正确'
      username: 'kobe'
      password: 666666
    
    -
      name: '用户名为空'
      username:
      password: 666666
    
    -
      name: '用户名或者密码错误'
      username: 'james'
      password: 666666
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    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')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    读取结果:

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

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    执行测试:

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

    在这里插入图片描述

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

    在这里插入图片描述

    test_json.json

    
    [
      {
        "name": "账号密码正确",
        "username": "kobe",
        "password": 666666
      },
      {
        "name": "用户名为空",
        "username": "",
        "password": 666666
      },
      {
        "name": "用户名或者密码错误",
        "username": "james",
        "password": 666666
      }
    ]
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    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')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    读取结果:

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

    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
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    四.对测试类参数化

    测试类的参数化,其实际上也是对类中的测试方法进行参数化。类中的测试方法的参数必须与@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
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    执行结果

    在这里插入图片描述


    在这里插入图片描述

  • 相关阅读:
    雷池WAF社区版的使用教程
    RabbitMQ、Kafka和RocketMQ比较
    怎么压缩成mp4视频?
    微服务架构改造案例
    JLink 添加新设备用于下载/调试固件
    简单了解GaussDB
    解决 Element的el-input 密码输入框浏览器自动填充账号密码问题
    如何使用递归,递归使用的技巧详解
    原生微信小程序实现手写签名功能
    计算机X86架构的描述
  • 原文地址:https://blog.csdn.net/YZL40514131/article/details/127602444