Python中Pytest测试框架的fixture使用详解

 更新时间:2023年08月03日 11:00:56   作者:橙子软件测试菇凉  
这篇文章主要介绍了Python中Pytest测试框架的fixture使用详解,Pytest的fixture的目的是提供一个测试的基线,在此基线基础上,可以更可靠的进行重复测试,需要的朋友可以参考下

1、fixture的含义

fixture的目的是提供一个测试的基线,在此基线基础上,可以更可靠的进行重复测试。

2、fixture的优势

Pytest的fixture相对于传统的xUnit的setup/teardown函数做了显著的改进:

(1)测试fixture有明确的名称,通过在函数/模块/类或者整个项目中激活来使用

(2)测试fixture是模块化的实现,使用fixture名即可触发特定的fixture,fixture可以在其他fixture中进行使用测试fixture不仅可以进行简单的单元测试,也可以进行复杂的功能测试。可以根据配置和组件的选项进行参数化定制测试,或者跨函数/类/模块或者整个测试过程进行测试。

(3)pytest依然支持经典的xUnit的样式,你可以根据自己的喜好混合两种样式。

3、fixture参数

  • scope
  • params
  • autouse
  • ids
  • name
def fixture(
    fixture_function: Optional[_FixtureFunction] = None,
    *,
    scope: "Union[_Scope, Callable[[str, Config], _Scope]]" = "function",
    params: Optional[Iterable[object]] = None,
    autouse: bool = False,
    ids: Optional[
        Union[
            Iterable[Union[None, str, float, int, bool]],
            Callable[[Any], Optional[object]],
        ]
    ] = None,
    name: Optional[str] = None,
) -> Union[FixtureFunctionMarker, _FixtureFunction]:
    """Decorator to mark a fixture factory function.
    This decorator can be used, with or without parameters, to define a
    fixture function.
    The name of the fixture function can later be referenced to cause its
    invocation ahead of running tests: test modules or classes can use the
    ``pytest.mark.usefixtures(fixturename)`` marker.
    Test functions can directly use fixture names as input arguments in which
    case the fixture instance returned from the fixture function will be
    injected.
    Fixtures can provide their values to test functions using ``return`` or
    ``yield`` statements. When using ``yield`` the code block after the
    ``yield`` statement is executed as teardown code regardless of the test
    outcome, and must yield exactly once.
    :param scope:
        The scope for which this fixture is shared; one of ``"function"``
        (default), ``"class"``, ``"module"``, ``"package"`` or ``"session"``.
        This parameter may also be a callable which receives ``(fixture_name, config)``
        as parameters, and must return a ``str`` with one of the values mentioned above.
        See :ref:`dynamic scope` in the docs for more information.
    :param params:
        An optional list of parameters which will cause multiple invocations
        of the fixture function and all of the tests using it. The current
        parameter is available in ``request.param``.
    :param autouse:
        If True, the fixture func is activated for all tests that can see it.
        If False (the default), an explicit reference is needed to activate
        the fixture.
    :param ids:
        List of string ids each corresponding to the params so that they are
        part of the test id. If no ids are provided they will be generated
        automatically from the params.
    :param name:
        The name of the fixture. This defaults to the name of the decorated
        function. If a fixture is used in the same module in which it is
        defined, the function name of the fixture will be shadowed by the
        function arg that requests the fixture; one way to resolve this is to
        name the decorated function ``fixture_<fixturename>`` and then use
        ``@pytest.fixture(name='<fixturename>')``.
    """
    fixture_marker = FixtureFunctionMarker(
        scope=scope, params=params, autouse=autouse, ids=ids, name=name,
    )
    # Direct decoration.
    if fixture_function:
        return fixture_marker(fixture_function)
    return fixture_marker

4、实战一:fixture作为参数使用

测试函数可以通过接受一个已经命名的fixture对象来使用它们。对于每个参数名,如果fixture已经声明定义,会自动创建一个实例并传入该测试函数。

fixture函数通过装饰器标志@pytest.fixture来注册。

下面是一个简单的独立的测试模块,包含一个fixture及使用它的测试函数。

使用场景:

  • 用例1需要登录
  • 用例2不需要登录
  • 用例3需要登录

用法

在方法前面加@pytest.fixtrue()

实战

  • 单个fixture
import pytest
@pytest.fixture()
def login():
    print("这个是登录方法")
def test_case1(login):
    print("test_case1,需要登录")
    pass
def test_case2():
    print("test_case2,不用登录")
    pass
def test_case3(login):
    print("test_case3,需要登录")
    pass
if __name__ == '__main__':
    pytest.main()

在这里插入图片描述

  • 多个fixture
import pytest
//名字可以作为参数
@pytest.fixture()
def login():
    print("这个是登录方法")
    return ('tom',"123")
@pytest.fixture()
def operate():
    print("登录后的操作")
def test_case1(login,operate):
    print(login)
def test_case2():
    print("test_case2,不用登录")
def test_case3(login):
    print(login)
if __name__ == '__main__':
    pytest.main()

在这里插入图片描述

5、实战二:fixture的作用范围

测试函数可以通过接受一个已经命名的fixture对象来使用他们。

对于每个参数名,如果fixture已声明定义,会自动创建一个实例并传入该测试函数。fixture函数通过装饰器标志@pytest.fixture来注册。

下面是一个简单的独立的测试模块,包含一个fixture及使用它的测试函数

名称范围说明
function函数级每一个函数或方法都会调用
class类级别每个测试类只运行一次
module模块级每一个.py文件调用一次
package包级每一个python包只调用一次(暂不支持)
session会话级每次会话只需要运行一次,会话内所有方法及类,模块都共享这个方法

作用范围顺序:session》module》class》function

使用场景

整个模块有多条测试用例,需要在全部用例执行之前打开浏览器,全部执行之后去关闭浏览器,打开和关闭操作只执行一次。

import pytest
# 作用域:module是在模块之前执行,模块之后执行
@pytest.fixture(scope="module")
def open():
    print("打开浏览器")
    yield
    print("执行teardown!")
    print("最后关闭浏览器")
@pytest.mark.usefixtures("open")
def test_search1():
    print("test_search1")
def test_search2(open):
    print("test_search2")
def test_search3(open):
    print("test_search3")

return 与 yield的区别:

  • return:在程序函数中返回某个值,返回之后函数不在继续执行,彻底结束。
  • yield: 带有yield的函数是一个迭代器,函数返回某个值时,会停留在某个位置,返回函数值后,会在前面停留的位置继续执行直到程序结束

6、实战三:fixture与conftest.py结合使用

在使用之前我们先来了解什么是conftest.py?

实现测试用例的过程中,当你发现需要使用来自多个文件的fixture函数的时候,可以将这些fixture函数放到conftest.py中。

你不需要导入这些fixture函数,它会由pytest自动检索。

fixture函数的检索顺序是从测试类开始,然后测试的模块,然后就是conftest.py文件,最后是内置的插件和第三方插件。

使用场景

你与其他测试工程师合作一起开发时,公共的模块要在不同文件中,要在大家都访问到的地方(建议可以放在项目的根目录,因为找到conftest.py文件,先在同级目录找,如果同级目录找不到时,会向上级目录继续找,指导找到为止)

ps:conftest.py名称是固定,不能修改

实战

conftest.py的内容如下:

import pytest
#这个一定不要忘记写
@pytest.fixture(scope="session")
def login():
    # setup操作
    print("用户需要先完成登录操作")
    username = "hxc"
    name = "pytest书籍"
    # 相当于return,但是return不会执行后面的语句,yield是可以
    yield username,name
    # teardown操作
    print("完成登出操作")

test_conftestDemo.py的内容如下:

import pytest
def test_search(login):
    username,name = login
    print(f"用户名:{username},搜索商品:{name}")
def test_cart(login):
    print("添加购物车")
def test_order():
    print("下单pytest书籍")
def test_login(login):
    print("添加购物车之前先登录")
def test_get_product(connectDB):
    print("获取商品信息先连接数据库")
@pytest.fixture()
def connectDB():
    print("连接数据库")
    yield
    print("断开数据库")

在这里插入图片描述

7、实战四:fixture参数化

测试过程中需要大量的测试数据,如果每一个测试用例都编写一条测试用例,用例将是非常庞大的。

一般会使用将测试用例用到的数据一参数的形式传入待测试用例中,并为每条测试数据生成一个测试结果数据。

使用场景

测试离不开数据,为了数据灵活,一般数据都是通过参数传的

使用方法

在fixture方法上加装饰器@pytest.fixture(params=[1,2,3]),就会传入三个数据1,2,3,分别将这三个数据传入到用例当中。传入的数据需要使用一个固定的参数名request来接收。

import pytest
@pytest.fixture(params=["selenium", "appium"])
def login(request):
    print(f"用户名:{request.param}")
    return request.param
def test_demo1(login):
    print(f"demo1 case 数据为: {login}")

在这里插入图片描述

import pytest
@pytest.fixture(params=[["selenium",123],["appium",123456]])
def login(request):
    print(f"用户名:{request.param}")
    return request.param
def test_demo1(login):
    print(f"demo1 case: 数据为: {login}")

在这里插入图片描述

到此这篇关于Python中Pytest测试框架的fixture使用详解的文章就介绍到这了,更多相关Pytest框架的fixture内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • python常见读取语音的3种方法速度对比

    python常见读取语音的3种方法速度对比

    python已经支持WAV格式的书写,下面这篇文章主要给大家介绍了关于python常见读取语音的3种方法速度对比的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-12-12
  • Python文件读写w+和r+区别解析

    Python文件读写w+和r+区别解析

    这篇文章主要介绍了Python文件读写w+和r+区别解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • Python编程快速上手——选择性拷贝操作案例分析

    Python编程快速上手——选择性拷贝操作案例分析

    这篇文章主要介绍了Python选择性拷贝操作,结合具体实例形式分析了Python文件遍历、查找、复制拷贝等相关操作技巧,需要的朋友可以参考下
    2020-02-02
  • Python的加密模块之hashlib 与 base64详解及常用加密方法

    Python的加密模块之hashlib 与 base64详解及常用加密方法

    我们来学习一下 Python 中的加密模块,加密模块在工作中被广泛应用,比如数据的传入 不希望被捕获,通过把数据加密。这样即使被捕获也无法获取到数据的真实信息,今天我们就来学习一下关于加密的方法,感兴趣的朋友跟随小编一起看看吧
    2023-02-02
  • python线程信号量semaphore使用解析

    python线程信号量semaphore使用解析

    这篇文章主要介绍了python线程信号量semaphore使用解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • python使用turtle库写六角形的思路与代码

    python使用turtle库写六角形的思路与代码

    学习Python,接触到turtle包,就用它来画一下六边形,下面这篇文章主要给大家介绍了关于python使用turtle库写六角形的思路与代码,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-11-11
  • Windows环境打包python工程为可执行程序的详细过程

    Windows环境打包python工程为可执行程序的详细过程

    我的开发环境是windows7,然后系统是64位,安装的python和wxpython都是32位的,本文记录我怎样用pyinstaller打包我用python开发的工程,在网上搜索了很多资源,基本上都是不全的,所以我在这儿记录一下这个比较完整的过程,一起看看吧
    2024-01-01
  • 详解python中Numpy的属性与创建矩阵

    详解python中Numpy的属性与创建矩阵

    这篇文章给大家分享了关于python中Numpy的属性与创建矩阵的相关知识点内容,有兴趣的朋友们可以学习参考下。
    2018-09-09
  • python实现按日期归档文件

    python实现按日期归档文件

    这篇文章主要介绍了python实现如何按日期归档文件,帮助大家更好的理解和使用python,感兴趣的朋友可以了解下
    2021-01-01
  • Python如何在main中调用函数内的函数方式

    Python如何在main中调用函数内的函数方式

    这篇文章主要介绍了Python如何在main中调用函数内的函数方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-06-06

最新评论