• pytest之参数化parametrize的使用


    参考:

    https://www.cnblogs.com/benben-wu/p/11542411.html

    https://blog.csdn.net/liudinglong1989/article/details/106206212

    前言

    unittest框架使用的第三方库ddt来参数化的,而pytest框架就直接使用装饰器@pytest.mark.parametrize来对测试用例进行传参。这个是针对测试方法来参数化,还有一种是针对前置处理函数来传参。但往往这两种是可以结合使用。

    fixture之Params参数化(单个列表)

    前面讲fixture函数时,它有个参数params用来传递参数,并且与request结合使用,先看单个:

    import pytest
     
    seq = [1, 2, 3]
     
     
    @pytest.fixture(params=seq)
    def test_data(request):
        print("参数")
        return request.param
     
     
    class TestData:
        def test_1(self, test_data):
            print("用例", test_data)
     
     
    if __name__ == '__main__':
          pytest.main()
    
    —————————————————————————————————
    
    运行结果:
    fixture_test03.py::TestData::test_1[1] 参数
    PASSED                            [ 33%]用例 1
     
    fixture_test03.py::TestData::test_1[2] 参数
    PASSED                            [ 66%]用例 2
     
    fixture_test03.py::TestData::test_1[3] 参数
    PASSED                            [100%]用例 3
     
     
    ============================== 3 passed in 0.05s ==============================

      

      

    fixture之Params参数化(单个列表嵌套其他格式)

    列表里有多个dict数据,request会自动化循环读取每个索引下的值,从0开始,看下面例子:

    注意:params需要与request一起使用。

    import pytest
    
    seq = [{'a':1,'b':2},{'c':3,'d':4}]
    
    
    @pytest.fixture(params=seq)
    def test_data(request):
      print("参数:%s"%request.param)
      return request.param
    
    
    class TestData:
    def test_1(self, test_data):
      print("用例", test_data)
    
    
    
    
    if __name__ == '__main__':
        pytest.main()
      
    —————————————————————————————————
    
     运行结果:
    
    ============================== 2 passed in 0.04s ==============================
    
    Process finished with exit code 0
    参数:{'a': 1, 'b': 2}
    PASSED [ 50%]用例 {'a': 1, 'b': 2}
    参数:{'c': 3, 'd': 4}
    PASSED [100%]用例 {'c': 3, 'd': 4}
      

    装饰器@pytest.mark.parametrize参数化(单个列表)

    # 方式一:直接写
    @pytest.mark.parametrize("a", ['北京','上海','重庆'])
    def test_add01(a):
        print(a)
    
    data = ['北京','上海','重庆']
    # 方式二:参数为列表
    @pytest.mark.parametrize("a", data)
    def test_add02(a):
        print(a)

    装饰器@pytest.mark.parametrize参数化(单个列表嵌套其他格式)

    import pytest
    test_datas = [
        (11, 22, 33),
        (22, 33, 55)
    ]
    
    datas_dict = [
        {"a": 1, "b": 2, "c": 3},
        {"a": 11, "b": 22, "c": 33},
        {"a": 111, "b": 222, "c": 333},
    ]
    
    # 方式一:直接写
    @pytest.mark.parametrize("a, b, c", [(1, 2, 3), (4, 5, 9)])
    def test_add01(a, b, c):
        res = a + b
        assert res == c
    
    # 方式二:参数为列表中嵌套元组
    @pytest.mark.parametrize("data", test_datas)
    def test_add02(data):
        res = data[0] + data[1]
        assert res == data[2]
    
    # 方式三:参数为列表中嵌套字典
    @pytest.mark.parametrize("data", datas_dict)
    def test_add03(data):
        res = data["a"] + data["b"]
        assert res == data["c"]

    装饰器@pytest.mark.parametrize参数化(多个组合)

    #若要获得多个参数化参数的所有组合,可以堆叠参数化装饰器
     
    import pytest
    @pytest.mark.parametrize("a",[0,1])
    @pytest.mark.parametrize("b",[3,4])
    def test_01(a,b):
        print("测试数据组合:a->%s,b->%s"%(a,b))
     
    if __name__ == "__main__":
        pytest.main(["-s", "test_3.py"])
    
    
    _______________________________________________________运行结果:
    test_123.py 测试数据组合:a->0,b->3
    .测试数据组合:a->1,b->3
    .测试数据组合:a->0,b->4
    .测试数据组合:a->1,b->4
    import pytest
    
    
    @pytest.mark.parametrize("a", [0, 1])
    @pytest.mark.parametrize("b", [3, 4])
    @pytest.mark.parametrize("c", [2, 6])
    def test_01(a, b, c):
        print("测试数据组合:a->%s,b->%s,c->%s" % (a, b, c))
    
    
    if __name__ == "__main__":
        pytest.main(["-s", "test_123.py"])
    
    ———————————————————————————————————
    运行结果:
    test_123.py 测试数据组合:a->0,b->3,c->2
    .测试数据组合:a->1,b->3,c->2
    .测试数据组合:a->0,b->4,c->2
    .测试数据组合:a->1,b->4,c->2
    .测试数据组合:a->0,b->3,c->6
    .测试数据组合:a->1,b->3,c->6
    .测试数据组合:a->0,b->4,c->6
    .测试数据组合:a->1,b->4,c->6
    .

     

    单个fixture与@pytest.mark.parametrize组合

    如果装饰器@pytest.mark.parametrize与request结合使用,如果测试方法写在类中,则@pytest.mark.parametrize的参数名称要与@pytest.fixture函数名称保持一致。并且要添加indirect=True参数,目的是把ss_data当做函数去执行,而不是参数

    根据开关indirect自由控制,默认是False当做参数。indirect是True则当做函数

    单个参数--例子1.1  参数是列表格式,indirect=True

    import pytest
    seq = [1,2,3]
    @pytest.fixture()
    def ss_data(request):
        print("参数:%s"%request.param)
        return request.param
     
     
     
    class TestData:
        @pytest.mark.parametrize("ss_data",seq,indirect=True)
        def test_1(self,ss_data):
            print("用例", ss_data)
     
    if __name__ == '__main__':
        pytest.main()
    
    
    —————————————————————————————————运行结果:
    test_123.py 参数:1
    用例 1
    .参数:2
    用例 2
    .参数:3
    用例 3
    .

    单个参数--例子1.2  参数是列表格式,indirect=False

    如果不使用fixture装饰器函数,也不使用外部函数,也是可以的,indirect默认是False例子如下:

    import pytest
    seq = [1,2,3]
     
    class TestData:
        @pytest.mark.parametrize("x",seq,indirect=False)
        def test_1(self,x):
            print("用例", x)
     
    if __name__ == '__main__':
        pytest.main()
    
    ———————————————————————————————————运行结果:
    test_123.py 用例 1
    .用例 2
    .用例 3
    .

    单个参数--例子2  参数是列表嵌套元组格式,indirect=True

    import pytest
    seq = [(1,2),(3,4)]
     
    @pytest.fixture()
    def get_data(request):
        x = request.param[0]
        y = request.param[1]
        print(x,111)
        print(y,222)
        # print(request.param)
        pass
     
    # indirect=True声明x是个函数
    @pytest.mark.parametrize("get_data",seq,indirect=True) 
    def test_data(get_data):
      print(get_data)

    if __name__ == '__main__':
      pytest.main()
    —————————————————————————————————
    运行结果:

    test_123.py 1 111
    2 222
    None
    .3 111
    4 222
    None
    .

    多个fixture与@pytest.mark.parametrize组合

    参数化装饰器也可以叠加,使用parametrize装饰器叠加时,用例组合是2个参数个数相乘

    import pytest
     
    seq1 = [1,2,3]
    seq2 = [4,5,6]
     
    @pytest.fixture()
    def get_seq1(request):
        seq1 = request.param
        print("seq1:",seq1)
        return seq1
     
    @pytest.fixture()
    def get_seq2(request):
        seq2 = request.param
        print("seq2:", seq2)
        return seq2
     
    @pytest.mark.parametrize("get_seq1",seq1,indirect=True)
    @pytest.mark.parametrize("get_seq2",seq2,indirect=True)
    def test_1(get_seq1,get_seq2):
        print(get_seq1,11)
        print(get_seq2,22)
     
    if __name__ == '__main__':
        pytest.main()
    
    —————————————————————————————————
    
    运行结果:
    test_123.py seq1: 1
    seq2: 4
    1 11
    4 22
    .seq1: 2
    seq2: 4
    2 11
    4 22
    .seq1: 3
    seq2: 4
    3 11
    4 22
    .seq1: 1
    seq2: 5
    1 11
    5 22
    .seq1: 2
    seq2: 5
    2 11
    5 22
    .seq1: 3
    seq2: 5
    3 11
    5 22
    .seq1: 1
    seq2: 6
    1 11
    6 22
    .seq1: 2
    seq2: 6
    2 11
    6 22
    .seq1: 3
    seq2: 6
    3 11
    6 22
    .
  • 相关阅读:
    Ubuntu 18.04 安装博通(Broadcom)无线网卡驱动
    Python3漏洞扫描工具 ( Python3 插件式框架 )
    Linux 防火墙
    基于Python3的漏洞检测工具 ( Python3 插件式框架 )
    git学习笔记
    sublime text 3 优化配置
    win10 出现0x80072efd错误
    Ubuntu搭建NFS服务器,NFS协议详细分析
    docker实现跨主机连接
    Python-RabbitMQ(持久化)
  • 原文地址:https://www.cnblogs.com/lijinglj/p/15309042.html
Copyright © 2020-2023  润新知