• pytest学习4-fixtures


    源码注释:

    def fixture(scope="function", params=None, autouse=False, ids=None, name=None):
    
     """这是一个标记工厂函数的装饰器.
    不管是否带有参数,这个装饰器是用来定义一个fixture函数.
    fixture函数的函数名被引用后,能够在运行测试用例前被调用:
    测试模块或类可以使用pytest.marker.usefixtures(fixturename)来标记.
    
    测试用例函数可以直接使用被装饰的fixture名称,作为测试函数的输入参数,在这种情况下,
    fixture函数将返回一个fixture实例来注入测试用例函数,即作为入参传递。
    
    fixture可以使用‘return’或者‘yield’语句来返回他们的值.使用‘yield’时,
    ‘yield’语句后的代码块将作为teardown代码执行,不管测试结果如何,必须只生成一次,
    也就是说yield语句后的代码只有在最后一次调用后执行.
    
    :参数 scope: 共享scope范围的fixture, 有以下几种:
                ``"function"`` (默认), ``"class"``, ``"module"``,
                ``"session"``,``"package"``(实验中) .
    
    :参数 params: 一个可选的参数列表,能够使得fixture函数的多次调用和所有测试用例函数使用它.
    
    :参数 autouse: 如果为True,那么该fixture函数将被激活,所有测试对象都能使用;
    如果为False,那么激活该fixture函数需要显式引用.
    
    :参数 ids: 字符串ids的列表,每个id对应着参数,以便于他们是测试id的一部分,
    如果没有提供id,那么将由参数自动生成.
    
    :参数 name: fixture的名称,默认是被装饰的函数的名字.
    如果一个fixture在同一个模块中被定义使用,那么该fixture的函数名将被请求fixture的函数参数隐藏. 
    解决此问题的方法是命名该装饰函数:
    ``fixture_<fixturename>````@pytest.fixture(name='<fixturename>')``.
    """
    

    fixture的作用范围

        + fixture里面有个scope参数可以控制fixture的作用范围:session>module>class>function
        + -function:每一个函数或方法都会调用
        + -class:每一个类调用一次,一个类中可以有多个方法
        + -module:每一个.py文件调用一次,该文件内又有多个function和class
        + -session:是多个文件调用一次,可以跨.py文件调用,每个.py文件就是module
        1.fixture为function级别的时候,它的作用范围是每个测试用例来之前运行一次,销毁代码在测试用例之后运行。
        2.fixture为class级别的时候,如果一个class里面有多个用例,都调用了次fixture,那么此fixture只在此class里所有用例开始前执行一次。
        3.fixture为module时,在当前.py脚本里面所有用例开始前只执行一次。
        4.fixture为session级别是可以跨.py模块调用的,也就是当我们有多个.py文件的用例的时候,如果多个用例只需调用一次fixture,那就可以设置为scope="session",并且写到conftest.py文件里。
    

    fixture的调用:

    定义fixture跟定义普通函数差不多,唯一区别就是在函数上加个装饰器@pytest.fixture(),fixture命名不要以test开头,跟用例区分开。fixture是有返回值得,没有返回值默认为None。用例调用fixture的返回值,直接就是把fixture的函数名称当做变量名称。
    例如:
            import pytest
            @pytest.fixture()
            def test():
                list1=[1,2,3,4,5,6]
                return list1
            def test_func(test):
                 print("传入的参数:"+str(test))
                for i in test:
                assert 1==i
        输出:
        ============================ test session starts ==============================
        test_fix-1.py 传入的参数:[1, 2, 3, 4, 5, 6]
        @pytest.fixture()装饰器用于声明函数是一个fixture,如果测试函数的参数列表中包含fixture名,那么pytest会检测到,并在测试函数运行之前执行该fixture。fixture可以完成任务,也可以返回数据给测试函数。
        建议:被fixture装饰的函数别以test命名,比如上面的命名为some_data,而不是test_data。当然,这样命名也没有错,只是为了方便区分是fixture还是测试用例(函数)
    

    多个fixture调用:

        如果用例需要用到多个fixture的返回数据,fixture也可以返回一个元祖,list或字典,然后从里面取出对应数据。
        import pytest
        @pytest.fixture()
        def data1():
                list1=[1,2,3,4,5,6]
                return list1
        @pytest.fixture()
        def data2():
            list1=[3,4,5,6,7,8]
            return list1
        def test_func(data1,data2):
            print("传入的参数:"+str(data1))
            print("传入的参数:"+str(data2))
            assert len(data1)==len(data2)
        if __name__ == '__main__':
            pytest.main["-s","test_fix-1.py"]
        输出:
        test_fix-1.py 传入的参数:[1, 2, 3, 4, 5, 6]
        传入的参数:[3, 4, 5, 6, 7, 8]
        .
    

    conftest.py

        fixture可以放在单独的测试文件里,如果你希望多个测试文件共享fixture,可以在某个公共目录下新建一个conftest.py文件,将fixture放在其中。
        如果你希望fixture的作用域仅限于某个测试文件,那么将它写在该测试文件里。可以供所在目录及其子目录下的测试使用。
        说明:
        尽管conftest.py是python模块,但它不能被当测试文件导入,import conftest的用法是不允许出现的。
        例如:
        conftest.py:
        import pytest
        @pytest.fixture()    
        def data_list():
            return [1,2,3,4,5,6]
        test_fix-1.py:
        def test_func(data_list):
            print("传入的参数:"+str(data_list))
            assert len(data_list)==4
        运行结果:test_fix-1.py 传入的参数:[1, 2, 3, 4, 5, 6]
        当pytest执行test_func函数时,会自动去conftest.py里找data_list并执行,这样比如我们的用例,有些需要登录,有些不需要登录,我们可以给需要登录的用例加上fixture.
    

    fixture配置及yield

         fixture会在测试函数之前运行,但如果fixture函数包含yield,那么系统会在yield处停止,转而执行测试函数,等测试函数执行完毕后再回到fixture,继续执行yield后面的代码。因此,可以将yield之前的代码视为配置(setup)过程,将yield之后的代码视为清理(teardown)过程,无论测试过程中发生了什么,yield之后的代码都会被执行
        例如以下代码:
        @pytest.fixture(scope="module")
        def data_list():
            print("打开浏览器,并且打开百度首页")
            yield
            print("执行teardown!")
            print("最后关闭浏览器")
        def test_func(data_list):
            print("开始执行测试用例一")
        def test_func1(data_list):
            print("开始执行测试用例二")
        输出结果:
        test_fix-1.py 打开浏览器,并且打开百度首页
        开始执行测试用例一
       .开始执行测试用例二
        .执行teardown!
        最后关闭浏览器
    

    --setup-show

        上面的运行结果中,没有具体看到执行结果,可以加入参数--setup-show查看具体执行过程,命令:pytest -s --setup-show test_fix-1.py 
    

    设置autouse=True

        平常写自动化用例会写一些前置的fixture操作,用例需要用到就直接传该函数的参数名称就行了。当用例很多的时候,每次都传这个参数,会比较麻烦。fixture里面有个参数autouse,默认是Fasle没开启的,可以设置为True开启自动使用fixture功能,这样用例就不用每次都去传参了。
        代码:
        @pytest.fixture(scope="session",autouse=True)
        def data_list():
                print("打开浏览器,并且打开百度首页")
                yield
                print("执行teardown!")
                print("最后关闭浏览器")
    

    使用usefixture方法

        使用装饰器@pytest.mark.usefixtures()修饰需要运行的用例
        代码如下:      
        @pytest.mark.usefixtures("data_list")
        def test_func():
            print("开始执行测试用例一")
        @pytest.mark.usefixtures("date_list")
        def test_func1():
            print("开始执行测试用例二")
  • 相关阅读:
    杂项
    导出查询数据(大数据量)
    设置现有字段自增
    C++ 矩形交集和并集的面积-离散化
    Python使用flask架构、跨域
    匈牙利命名法
    C++ main函数
    windows编译boost
    mfc HackerTools监控键盘按键
    mfc HackerTools远程线程注入
  • 原文地址:https://www.cnblogs.com/qixc/p/12167484.html
Copyright © 2020-2023  润新知