• pytest4-fixture的使用


    fixture的作用:作用类似unittest中setup/teardown,它的优势是可以跨文件共享

    fixture的格式:在普通函数上加上装饰器@pytest.fixture(),且函数名不能以test_开头,目的是与测试用例做区分

    一 fixture的三种调用方式

    1.在测试用例中  直接把fixture的函数名称作为参数传入  进行调用

    fixture如何使用?fixture可以有返回值,如果没有return默认但会None;用例调用fixture的返回值,就是直接把fixture的函数名称作为参数传入。

    特别说明:用例断言失败是failed,fixture断言失败是error

    fixture的作用范围

    demo1:fixture可以返回一个元组、列表或字典

    # test_01.py
    import pytest
    
    
    @pytest.fixture()
    def user():
        print("用户名")
        name = 'wangmm'
        password = '123456'
        return name,password
    
    
    def test_a(user):
        u = user[0]
        p = user[1]
        assert u == 'wangmm'
    
    执行结果:
    D:myprojectpytest_demo	estcases>pytest -vs test_01.py
    =================================================================================== test session starts ====================================================================================
    platform win32 -- Python 3.6.5, pytest-5.0.1, py-1.8.0, pluggy-0.12.0 -- d:softpython36python.exe
    cachedir: .pytest_cache
    rootdir: D:myprojectpytest_demo	estcases
    collected 1 item                                                                                                                                                                            
    
    test_01.py::test_a 用户名
    PASSED
    
    ================================================================================= 1 passed in 0.03 seconds =================================================================================

    demo2:test_用例传多个fixture参数

    # test_02.py
    import pytest
    
    
    @pytest.fixture()
    def username():
        name = 'wangmm'
        return name
    
    
    @pytest.fixture()
    def pw():
        password = '123456'
        return password
    
    
    def test_user(username, pw):
        assert username == 'wangmm'
        assert pw == '123456'
    
    执行结果:
    D:myprojectpytest_demo	estcases>pytest -vs test_02.py
    =================================================================================== test session starts ====================================================================================
    platform win32 -- Python 3.6.5, pytest-5.0.1, py-1.8.0, pluggy-0.12.0 -- d:softpython36python.exe
    cachedir: .pytest_cache
    rootdir: D:myprojectpytest_demo	estcases
    collected 1 item                                                                                                                                                                            
    
    test_02.py::test_user PASSED
    
    ================================================================================= 1 passed in 0.03 seconds =============================================    ====================================

    demo3:fixture与fixture间相互调用

    # test_03.py
    import pytest
    
    @pytest.fixture()
    def first():
        a = "wangmm"
        return a
    
    @pytest.fixture()
    def sencond(first):
        '''psw调用user fixture'''
        a = first
        b = "123456"
        return (a, b)
    
    def test_1(sencond):
        '''用例传fixture'''
        assert sencond[0] == "wangmm"
        assert sencond[1] == "123456"
    
    输出结果:
    D:myprojectpytest_demo	estcases>pytest -vs test_03.py
    =================================================================================== test session starts ====================================================================================
    platform win32 -- Python 3.6.5, pytest-5.0.1, py-1.8.0, pluggy-0.12.0 -- d:softpython36python.exe
    cachedir: .pytest_cache
    rootdir: D:myprojectpytest_demo	estcases
    collected 1 item                                                                                                                                                                                        
    
    test_03.py::test_1 PASSED

    2.使用usefixtures    但是需要注意如果fixture有返回值则不能使用usefixtures,usefixtures是获取不到返回值的

    @pytest.mark.usefixtures("user")
    def test_b():
        # u = user[0]
        # assert u == 'wangmm'
        assert  1 == 1

    3.使用autos自动调用fixture    注意:如果不传autouse,默认scope=False

    当然,如果需要用到fixture的返回结果,还是需要在入参中传入fixture

    @pytest.fixture(scope='function',autouse=True)
    def login_test():
        print("登录")


    def test_s7():    # 该测试用例不需要传login_test,会自动调用的
    print("用例1:登录之后其它动作111")

    二 使用conftest.py实现多文件共享fixture

    一个测试工程下是可以有多个conftest.py的文件,一般在工程根目录放一个conftest.py起到全局作用。
    在不同的测试子目录也可以放conftest.py,作用范围只在该层级以及以下目录生效。

    特别地:conftest.py不需要显示导入,pytest会自动读取该文件

    session > module > class > function

    @pytest.fixture(scope="session"):多个文件调用一次,可以跨.py,每个.py就是module

    @pytest.fixture(scope="module"):module级别的fixture在当前.py模块里,只会在用例第一次调用前执行一次

    @pytest.fixture(scope="class"):class级别的fixture,在每个类里,只会在第一次调用前执行一次

    @pytest.fixture(scope="function"):function级别,每个函数都会调用(默认)

    # conftest.py
    import pytest
    
    
    @pytest.fixture(scope="class")
    def login():
        print("登录系统")
    
    # test_fix.py
    import pytest
    
    
    class Test1:
        def test_s1(self,login):
            print("用例1:登录之后其它动作111")
    
        def test_s2(self):  # 不传login
            print("用例2:不需要登录,操作222")
    
        def test_s3(self, login):
            print("用例3:登录之后其它动作333")
    
    
    class Test2:
        def test_s4(self, login):
            print("用例4:登录之后其它动作444")
    
        def test_s5(self):  # 不传login
            print("用例5:不需要登录,操作555")
    
        def test_s6(self, login):
            print("用例6:登录之后其它动作666")
    
    
    输出结果:
    testcases	est_fix.py 登录系统
    用例1:登录之后其它动作111
    .用例2:不需要登录,操作222
    .用例3:登录之后其它动作333
    .登录系统
    用例4:登录之后其它动作444
    .用例5:不需要登录,操作555
    .用例6:登录之后其它动作666

     三 fixture中yield的作用

    Fixture finalization / executing teardown code 
    By using a yield statement instead of return, all the code after the yield statement serves as the teardown code.

     测试代码的执行顺序: yield前的代码-测试用例中的代码-yield后的代码


    demo1:

    # conftest.py
    import pytest
    import smtplib
    
    @pytest.fixture(scope='module')
    def smtp_connection():
        smtp_connection = smtplib.SMTP('smtp.126.com',25)
        yield smtp_connection
        print("teardown smtp")
        smtp_connection.close()
    
    # test_module.py
    def test_ehlo(smtp_connection):
        response, msg = smtp_connection.ehlo()
        assert response == 250
        # assert 0
    
    
    def test_noop(smtp_connection):
        response, msg = smtp_connection.noop()
        assert response == 250
        # assert 0
    
    输出结果:
    D:myprojectpytest_demo>pytest -qs --tb=no test_module.py      # --tb=no,指关闭回溯信息
    ..teardown smtp
    
    2 passed in 13.75 seconds

     四 多个fixture的执行顺序

    举例:

    import pytest
    
    order = []
    
    
    @pytest.fixture(scope='session')
    def s1():
        order.append("s1")
    
    
    @pytest.fixture(scope='module')
    def m1():
        order.append('m1')
    
    
    @pytest.fixture()
    def f1(f3):
        order.append('f1')
    
    
    @pytest.fixture()
    def f3():
        order.append('f3')
    
    
    @pytest.fixture(autouse=True)
    def a1():
        order.append('a1')
    
    
    @pytest.fixture()
    def f2():
        order.append('f2')
    
    
    def test_order(f1, m1, f2, s1):
        assert order == ["s1", "m1", "a1", "f3", "f1", "f2"]

    输出结果:1 passed  #即test_doder.py测试用例通过

    理论:

    session > module > class > function

    @pytest.fixture(scope="session"):多个文件调用一次,可以跨.py,每个.py就是module

    @pytest.fixture(scope="module"):module级别的fixture在当前.py模块里,只会在用例第一次调用前执行一次

    @pytest.fixture(scope="class"):class级别的fixture,在每个类里,只会在第一次调用前执行一次

    @pytest.fixture(scope="function"):function级别,每个函数都会调用(默认)

    def fixture(scope="function", params=None, autouse=False, ids=None, name=None):
    
        :arg scope: the scope for which this fixture is shared, one of
                    ``"function"`` (default), ``"class"``, ``"module"``,
                    ``"package"`` or ``"session"``.
    
                    ``"package"`` is considered **experimental** at this time.
    fixture源码

    特别地:平常写自动化用例会写一些前置的fixture操作,用例需要用到就直接传该函数的参数名称就行了。当用例很多的时候,每次都传这个参数,会比较麻烦。
    fixture里面有个参数autouse,默认是Fasle没开启的,可以设置为True开启自动使用fixture功能,这样用例就不用每次都去传参了

  • 相关阅读:
    SSH 多台VM之间无密码登录
    JavaScript Calling WebService by SOAP
    Excel大数据排查重复行内容方法,三步搞定!
    linux添加软件的service start/stop快捷服务(简单版)
    Linux服务器其中一个磁盘满了怎么办?在不做磁盘扩容的情况下,一个软连接就搞定。
    oracle数据库中将clob字段内容利用java提取出至文本文档中
    最全的常用正则表达式大全——包括校验数字、字符、一些特殊的需求等等
    mysql数据库误删除操作说明
    mysql5.x升级至mysql5.7后导入之前数据库date出错的解决方法!
    新建ftp账号,并使登陆者只访问当前目录
  • 原文地址:https://www.cnblogs.com/wang-mengmeng/p/11460287.html
Copyright © 2020-2023  润新知