• pytest文档14-函数传参和fixture传参数request


    转载地址:https://www.cnblogs.com/yoyoketang/p/9492132.html

     

    前言

    为了提高代码的复用性,我们在写用例的时候,会用到函数,然后不同的用例去调用这个函数。
    比如登录操作,大部分的用例都会先登录,那就需要把登录单独抽出来写个函数,其它用例全部的调用这个登陆函数就行。
    但是登录的账号不能写死,有时候我想用账号1去登录,执行用例1,用账号2去登录执行用例2,所以需要对函数传参。

    登录函数传参

    把登录单独出来,写一个函数,传2个参数user和psw,写用例的时候调用登录函数,输入几组user,psw参数化登录用例

    测试用例传参需要用装饰器@pytest.mark.parametrize,里面写两个参数

    • 第一个参数是字符串,多个参数中间用逗号隔开
    • 第二个参数是list,多组数据用元祖类型
    # test_01.py
    
    # coding:utf-8
    import pytest
    
    # ** 作者:上海-悠悠 QQ交流群:588402570**
    
    # 测试登录数据
    test_login_data = [("admin", "111111"),  ("admin", "")]
    
    def login(user, psw):
        '''普通登录函数'''
        print("登录账户:%s"%user)
        print("登录密码:%s"%psw)
        if psw:
            return True
        else:
            return False
    
    @pytest.mark.parametrize("user, psw", test_login_data)
    def test_login(user, psw):
        '''登录用例'''
        result = login(user, psw)
        assert result == True, "失败原因:密码为空"
    
    
    if __name__ == "__main__":
        pytest.main(["-s", "test_01.py"])

    运行结果

    ============================= test session starts =============================
    platform win32 -- Python 3.6.0, pytest-3.6.3, py-1.5.4, pluggy-0.6.0
    rootdir: D:\, inifile:
    plugins: metadata-1.7.0, html-1.19.0, allure-adaptor-1.7.10
    collected 2 items
    
    ............YOYOmarktest	est_01.py 登录账户:admin
    登录密码:111111
    .登录账户:admin
    登录密码:
    F
    user = 'admin', psw = ''
    
        @pytest.mark.parametrize("user, psw", [("admin", "111111"), ("admin", "")])
        def test_01(user, psw):
            result = login(user, psw)
    >       assert result == True
    E       assert False == True
    
    D:YOYOmarktest	est_01.py:18: AssertionError
    
    
    ================================== FAILURES ===================================
    _______________________________ test_01[admin-] _______________________________
    
    user = 'admin', psw = ''
    
        @pytest.mark.parametrize("user, psw", [("admin", "111111"), ("admin", "")])
        def test_01(user, psw):
            result = login(user, psw)
    >       assert result == True
    E       assert False == True
    
    D:YOYOmarktest	est_01.py:18: AssertionError
    ===================== 1 failed, 1 passed in 0.05 seconds ======================

    从结果可以看出,有2个用例,一个测试通过,一个测试失败了,互不影响

    request参数

    如果想把登录操作放到前置操作里,也就是用到@pytest.fixture装饰器,传参就用默认的request参数
    user = request.param 这一步是接收传入的参数,本案例是传一个参数情况

    # test_02.py
    # coding:utf-8
    import pytest
    
    #** 作者:上海-悠悠 QQ交流群:588402570**
    
    # 测试账号数据
    test_user_data = ["admin1", "admin2"]
    
    @pytest.fixture(scope="module")
    def login(request):
        user = request.param
        print("登录账户:%s"%user)
        return user
    
    @pytest.mark.parametrize("login", test_user_data, indirect=True)
    def test_login(login):
        '''登录用例'''
        a = login
        print("测试用例中login的返回值:%s" % a)
        assert a != ""
    
    
    if __name__ == "__main__":
        pytest.main(["-s", "test_02.py"])

    运行结果:

    ============================= test session starts =============================
    platform win32 -- Python 3.6.0, pytest-3.6.3, py-1.5.4, pluggy-0.6.0
    rootdir: D:\, inifile:
    plugins: metadata-1.7.0, html-1.19.0, allure-adaptor-1.7.10
    collected 2 items
    
    ............YOYOmarktest	est_02.py 登录账户:admin1
    测试用例中login的返回值:admin1
    .登录账户:admin2
    测试用例中login的返回值:admin2
    .
    
    ========================== 2 passed in 0.01 seconds ===========================

    添加indirect=True参数是为了把login当成一个函数去执行,而不是一个参数

    request传2个参数

    如果用到@pytest.fixture,里面用2个参数情况,可以把多个参数用一个字典去存储,这样最终还是只传一个参数
    不同的参数再从字典里面取对应key值就行,如: user = request.param["user"]

    # test_03.py
    # coding:utf-8
    import pytest
    
    # ** 作者:上海-悠悠 QQ交流群:588402570**
    
    # 测试账号数据
    test_user_data = [{"user": "admin1", "psw": "111111"},
                      {"user": "admin1", "psw": ""}]
    
    @pytest.fixture(scope="module")
    def login(request):
        user = request.param["user"]
        psw = request.param["psw"]
        print("登录账户:%s" % user)
        print("登录密码:%s" % psw)
        if psw:
            return True
        else:
            return False
    
    # indirect=True 声明login是个函数
    @pytest.mark.parametrize("login", test_user_data, indirect=True)
    def test_login(login):
        '''登录用例'''
        a = login
        print("测试用例中login的返回值:%s" % a)
        assert a, "失败原因:密码为空"
    
    
    if __name__ == "__main__":
        pytest.main(["-s", "test_03.py"])

    运行结果

    ============================= test session starts =============================
    platform win32 -- Python 3.6.0, pytest-3.6.3, py-1.5.4, pluggy-0.6.0
    rootdir: D:\, inifile:
    plugins: metadata-1.7.0, html-1.19.0, allure-adaptor-1.7.10
    collected 2 items
    
    ............YOYOmarktest	est_03.py 登录账户:admin1
    登录密码:111111
    测试用例中login的返回值:True
    .登录账户:admin1
    登录密码:
    测试用例中login的返回值:False
    F
    login = False
    
        @pytest.mark.parametrize("login", test_user_data, indirect=True)
        def test_login(login):
            '''登录用例'''
            a = login
            print("测试用例中login的返回值:%s" % a)
    >       assert a, "失败原因:密码为空"
    E       AssertionError: 失败原因:密码为空
    E       assert False
    
    D:YOYOmarktest	est_03.py:25: AssertionError
    
    
    ================================== FAILURES ===================================
    _____________________________ test_login[login1] ______________________________
    
    login = False
    
        @pytest.mark.parametrize("login", test_user_data, indirect=True)
        def test_login(login):
            '''登录用例'''
            a = login
            print("测试用例中login的返回值:%s" % a)
    >       assert a, "失败原因:密码为空"
    E       AssertionError: 失败原因:密码为空
    E       assert False
    
    D:YOYOmarktest	est_03.py:25: AssertionError
    ===================== 1 failed, 1 passed in 0.05 seconds ======================

    如果要用到login里面的返回值,def test_login(login)时,传入login参数,函数返回值就是login了

    多个fixtrue

    用例上面是可以同时放多个fixture的,也就是多个前置操作,可以支持装饰器叠加,使用parametrize装饰器叠加时,用例组合是2个参数个数相乘

    # test_04.py
    # ** 作者:上海-悠悠 QQ交流群:588402570**
    # coding:utf-8
    import pytest
    
    # 测试账号数据
    test_user = ["admin1", "admin2"]
    test_psw = ["11111", "22222"]
    
    
    @pytest.fixture(scope="module")
    def input_user(request):
        user = request.param
        print("登录账户:%s" % user)
        return user
    
    
    @pytest.fixture(scope="module")
    def input_psw(request):
        psw = request.param
        print("登录密码:%s" % psw)
        return psw
    
    
    
    @pytest.mark.parametrize("input_user", test_user, indirect=True)
    @pytest.mark.parametrize("input_psw", test_psw, indirect=True)
    def test_login(input_user, input_psw):
        '''登录用例'''
        a = input_user
        b = input_psw
        print("测试数据a-> %s, b-> %s" % (a,b))
        assert b
    
    if __name__ == "__main__":
        pytest.main(["-s", "test_04.py"])

    运行结果

    ============================= test session starts =============================
    platform win32 -- Python 3.6.0, pytest-3.6.3, py-1.5.4, pluggy-0.6.0
    rootdir: E:YOYOpar, inifile:
    plugins: metadata-1.7.0, html-1.19.0
    collected 4 items
    
    test_04.py 登录账户:admin1
    登录密码:11111
    测试数据a-> admin1, b-> 11111
    .登录账户:admin2
    测试数据a-> admin2, b-> 11111
    .登录密码:22222
    测试数据a-> admin2, b-> 22222
    .登录账户:admin1
    测试数据a-> admin1, b-> 22222
    .
    
    ========================== 4 passed in 0.05 seconds ===========================

    如果参数user有2个数据,参数psw有2个数据,那么组合起来的案例是两个相乘,也就是组合2*2 = 4个用例

  • 相关阅读:
    约束
    TCL(事务控制语言)
    MySQL常见约束
    “三大范式”及数据库设计
    同义词(别名)
    分享35个非常漂亮的单页网站设计案例
    Eclipse智能提示 (原创)
    java架构师之路:JAVA程序员必看的15本书的电子版下载地址
    Java初级学习笔记
    Java程序的汉化
  • 原文地址:https://www.cnblogs.com/peng-lan/p/11321251.html
Copyright © 2020-2023  润新知