• pytest--fixture


    前戏

    fixture是在测试函数运行前后,由pytest执行的外壳函数。fixture中的代码可以定制,满足多变的测试需求,包括定义传入测试中的数据集、配置测试前系统的初始状态、为批量测试提供数据源等等。

    下面是一个简单的fixture

    import pytest
    
    
    @pytest.fixture()
    def some_data():
        return 37
    
    
    def test_some_data(some_data):
        assert some_data == 37

    我们来运行一下

    @pytest.fixture()装饰器用于声明函数是一个fixture,如果测试函数的参数列表中包含fixture名,那么pytest会检测到,并在测试函数运行之前执行该fixture。fixture可以完成任务,也可以返回数据给测试函数。

    测试用例test_some_data()的参数列表中包含一个fixture名some_data,pytest会以该名称搜索fixture。pytest会优先搜索该测试所在的模块,然后搜索conftest.py

    建议:被fixture装饰的函数别以test命名,比如上面的命名为some_data,而不是test_data。当然,这样命名也没有错,只是为了方便区分是fixture还是测试用例(函数)

    conftest.py

    fixture可以放在单独的测试文件里,如果你希望多个测试文件共享fixture,可以在某个公共目录下新建一个conftest.py文件,将fixture放在其中。

    如果你希望fixture的作用域仅限于某个测试文件,那么将它写在该测试文件里。可以供所在目录及其子目录下的测试使用。

    说明:

    尽管conftest.py是python模块,但它不能被当测试文件导入,import conftest的用法是不允许出现的。

    我们将上面的代码更改

    conftest.py

    import pytest
    
    
    @pytest.fixture()
    def some_data():
        return 37

    test_fixture.py

    def test_some_data(some_data):
        assert some_data == 37

    当pytest执行test_some_data函数时,会自动去conftest.py里找some_data并执行,这样比如我们的用例,有些需要登录,有些不需要登录,我们可以给需要登录的用例加上fixture,当然,fixture也可以自定义使用范围,是函数,还是类,或者一个模块,后面会介绍。

    fixture配置及销毁yield

     fixture会在测试函数之前运行,但如果fixture函数包含yield,那么系统会在yield处停止,转而执行测试函数,等测试函数执行完毕后再回到fixture,继续执行yield后面的代码。因此,可以将yield之前的代码视为配置(setup)过程,将yield之后的代码视为清理(teardown)过程,无论测试过程中发生了什么,yield之后的代码都会被执行。

    将上面的conftest.py里的代码修改一下

    import pytest
    
    
    @pytest.fixture()
    def some_data():
        yield 37
        print('测试结束')

    --setup-show

    上面的测试,我们不会看到fixture的执行过程。如果希望看到测试过程中执行的是什么,以及执行的先后顺序,pytest提供的--setup-show选项可以实现这个功能

    我们的测试被夹在中间,pytest将每一个fixture的执行分成SETUP和TEARDOWN两部分。

    fixture名称前面的F代表的是fixture的作用范围,F代表函数级别的作用范围,如果是S,则代表的是会话级别的作用范围。

    指定fixture作用范围

     fixture包含一个叫scope(作用范围)的可选参数,用于控制fixture执行配置和销毁逻辑的频率。@pytest.fixture()的scope参数有四个带选值:function,class,module,session(默认值为function)。前面用到的fixture都没有指定scope,因此他们的作用范围都是默认的函数级别。

    scope=“function”

    函数级别的fixture每个测试函数只需要运行一次,配置代码在测试用例运行之前运行,销毁代码在测试用例运行之后运行。function是scope参数的默认值

     conftest.py

    import pytest
    
    
    @pytest.fixture(scope="function")  # 函数级别的
    def login():
        print('登录成功')

    test_fixture.py

    def test_index(login):
        print('访问index')
    
    
    def test_home(login):
        print('访问home')

    执行结果可以看到,我们在执行每个函数之前都执行了fixture

    scope=“class”

    类级别的fixture每个测试类只需要运行一次,无论测试类里有多少类方法都可以共享这个fixture

    conftest.py

    import pytest
    
    
    @pytest.fixture(scope="class")  # 类级别
    def login():
        print('登录成功')

    test_fixture.py

    class Test1():
        def test_index(self,login):
            print('访问index1')
    
        def test_home(self,login):
            print('访问home1')
    
    class Test2():
        def test_index(self,login):
            print('访问index2')
    
        def test_home(self,login):
            print('访问home2')

    scope=“module”

     模块级别的fixture,每个模块只需要运行一次,无论模块里有多少个测试函数、类方法或者其他fixture都可以共享这个fixture

    只需要修改conftest.py

    import pytest
    
    
    @pytest.fixture(scope="module")  # 模块级别
    def login():
        print('登录成功')

    scope=“session”

    会话级别的fixture,每次会话只需要运行一次,所有测试函数、方法都可以共享这个fixture

     我们把上面的test_fixture.py在复制一份,改名为test_fixture2,这样我们在testpytest下就有两个test文件了

     

    如果有两个文件,把session改为module,则会执行两次,因为有两个py文件

     使用usefixtures指定fixture

    目前为止用到fixture的测试,都是在测试函数的参数列表中指定fixture,实际上,也可以用@pytest.mark.usefixtures('fixture1', 'fixture2')标记测试函数或类。使用usefixtures,需要在参数列表中指定一个或多个fixture字符串。

    使用usefixture和在测试方法中添加fixture参数,二者本体上是差不多的,区别之一在与后者才能使用fixture的返回值

    import pytest
    
    
    @pytest.fixture(scope="function")
    def login():
        print('登录成功')
    conftest.py
    import pytest
    
    
    @pytest.mark.usefixtures('login')
    def test_index():
        print('访问index1')
    
    
    def test_home():
        print('访问home1')
    test_fixture2.py

    如果是类值需要在类名上面加上fixture

    import pytest
    
    
    @pytest.mark.usefixtures('login')
    class Test1():
        def test_index(self):
            print('访问index1')
    
        def test_home(self):
            print('访问home1')
    
    
    @pytest.mark.usefixtures('login')
    class Test2():
        def test_index(self):
            print('访问index2')
    
        def test_home(self):
            print('访问home2')
    类的fixture
    @pytest.mark.usefixtures("cleandir", "anotherfixture")指定多个fixture

    autouse

    不想源测试数据有任何改动,或全部都实现自动应用, 没特例,也都不需要返回值时可以选择自动应用

    使用fixture中参数autouse=True实现

    import pytest
    
    
    @pytest.fixture(autouse=True)
    def login():
        print('登录成功')
    conftest.py
    class Test1():
        def test_index(self):
            print('访问index1')
    
        def test_home(self):
            print('访问home1')
    
    
    class Test2():
        def test_index(self):
            print('访问index2')
    
        def test_home(self):
            print('访问home2')
    test_fixture.py
    def test_index():
        print('访问index1')
    
    
    def test_home():
        print('访问home1')
    test_fixture2.py

    可以看到,我们加了autouse=True之后,会给所有的方法都应用,不用再每个方法都使用fixture

     如果级别是class的话,则有class的只会执行一次

    为fixture重命名

     fixture的名字展示在使用它的测试或其他fixture函数的参数列表上,通常会和fixture函数名保持一致,但pytest允许使用@pytest.fixture()的name参数对fixture重命名

    conftest.py

    import pytest
    
    
    @pytest.fixture(name='login')  # 重命名为login
    def alibaba_taobao_app_login():
        print('登录成功')

    test_fixture2.py

    def test_index(login):
        print('访问index1')
    
    
    def test_home(login):
        print('访问home1')

    这个fixture原来的名字是 alibaba_taobao_app_login ,重命名后变成了login

     查看fixture

     我们可以使用--fixtures命令行选项,并提供所在测试文件名。pytest将列举所有可供测试使用的fixture,包括重命名的。我们自己重新定义的会出现在底部

  • 相关阅读:
    【云速建站】表单应用
    【云速建站】页面产品维护简述
    Forrester:华为云容器是容器混合云最佳选择
    AI如何驱动软件开发?华为云DevCloud 权威专家邀你探讨
    完美数据迁移-MongoDB Stream的应用
    补习系列(3)-springboot中的几种scope
    补习系列(2)-springboot mime类型处理
    关于Python的随机数模块,你必须要掌握!
    【Java】实战Java虚拟机之五“开启JIT编译”
    Jetty实战之 嵌入式Jetty运行Servlet
  • 原文地址:https://www.cnblogs.com/zouzou-busy/p/11298879.html
Copyright © 2020-2023  润新知