pytest学习和使用-fixture如何使用?

  • 和setup、teardown的区别是:fixture可自定义测试用例的前置条件;
  • setup、teardown针对整个脚本全局生效,可实现在执行用例前后加入一些操作;
  • setup、teardown不能做到灵活使用,比如用例A先登陆,用例B不需要登陆,用例C需要登陆,这样使用fixture更容易实现功能。

2.1 fixture源码

  • 部分源码如下:
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]:
  • 我们可看到有五个参数 scopeparamsautouseidsname,源码中也对着几个参数进行了说明,如下:
"""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
    .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  or
     statements. When using  the code block after the
     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  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 .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>').

"""
</fixturename></fixturename>

2.2 参数说明

  • 从以上部分源码以及说明我们可以看到:
fixture(scope="function", params=None, autouse=False, ids=None, name=None):

参数说明

默认:

,还有

默认:

,手动调用该fixture;为True,所有作用域内的测试用例都会自动调用该fixture

一个可选的参数列表

每个字符串id的列表

fixture的名称, 默认为装饰函数的名称,同一模块的fixture相互调用建议写个不同的name

  • 命名方式灵活,不局限于 setup 和teardown 这几个命名
  • conftest.py 配置里可以实现数据共享,不需要 import 就能自动找到fixture
  • scope=”module” 可以实现多个.py 跨文件共享前置
  • scope=”session” 以实现多个.py 跨文件使用一个 session 来完成多个用例

4.1 调用方式

-*- coding:utf-8 -*-
&#x4F5C;&#x8005;&#xFF1A;NoamaNelson
&#x65E5;&#x671F;&#xFF1A;2022/11/17
&#x6587;&#x4EF6;&#x540D;&#x79F0;&#xFF1A;test_mfixture.py
&#x4F5C;&#x7528;&#xFF1A;fixture&#x7684;&#x4F7F;&#x7528;
&#x8054;&#x7CFB;&#xFF1A;VX(NoamaNelson)
&#x535A;&#x5BA2;&#xFF1A;https://blog.csdn.net/NoamaNelson

import pytest

&#x4E0D;&#x5E26;&#x53C2;&#x6570;&#x65F6;&#x9ED8;&#x8BA4;scope="function"
@pytest.fixture
def case():
    print("&#x8FD9;&#x4E2A;&#x662F;&#x767B;&#x9646;&#x529F;&#x80FD;&#xFF01;")

def test_one(case):
    print("&#x7528;&#x4F8B;1&#x9700;&#x8981;&#x767B;&#x9646;,&#x7136;&#x540E;&#x8FDB;&#x884C;&#x64CD;&#x4F5C;one")

def test_two():
    print("&#x7528;&#x4F8B;2&#x4E0D;&#x9700;&#x8981;&#x767B;&#x9646;,&#x76F4;&#x63A5;&#x64CD;&#x4F5C;two")

def test_three(case):
    print("&#x7528;&#x4F8B;3&#x9700;&#x8981;&#x767B;&#x9646;,&#x7136;&#x540E;&#x64CD;&#x4F5C;three")

if __name__ == "__main__":
    pytest.main(["-s", "test_mfixture.py"])

Testing started at 10:33 ...

F:\pytest_study\venv\Scripts\python.exe "D:\JetBrains\PyCharm Community Edition 2020.2\plugins\python-ce\helpers\pycharm\_jb_pytest_runner.py" --path F:/pytest_study/test_case/test_d/test_mfixture.py
Launching pytest with arguments F:/pytest_study/test_case/test_d/test_mfixture.py in F:\pytest_study\test_case\test_d

============================= test session starts =============================
platform win32 -- Python 3.7.0, pytest-6.2.4, py-1.10.0, pluggy-0.13.1 -- F:\pytest_study\venv\Scripts\python.exe
cachedir: .pytest_cache
metadata: {'Python': '3.7.0', 'Platform': 'Windows-10-10.0.19041-SP0', 'Packages': {'pytest': '6.2.4', 'py': '1.10.0', 'pluggy': '0.13.1'}, 'Plugins': {'reportlog': '0.1.2', 'allure-pytest': '2.8.12', 'cov': '2.8.1', 'forked': '1.1.3', 'html': '2.0.1', 'metadata': '1.8.0', 'ordering': '0.6', 'xdist': '1.31.0'}, 'JAVA_HOME': 'D:\\jdk-11.0.8'}
rootdir: F:\pytest_study\test_case\test_d
plugins: reportlog-0.1.2, allure-pytest-2.8.12, cov-2.8.1, forked-1.1.3, html-2.0.1, metadata-1.8.0, ordering-0.6, xdist-1.31.0
collecting ... collected 3 items

test_mfixture.py::test_one              &#x8FD9;&#x4E2A;&#x662F;&#x767B;&#x9646;&#x529F;&#x80FD;&#xFF01;
PASSED                                  [ 33%]&#x7528;&#x4F8B;1&#x9700;&#x8981;&#x767B;&#x9646;,&#x7136;&#x540E;&#x8FDB;&#x884C;&#x64CD;&#x4F5C;one

test_mfixture.py::test_two PASSED       [ 66%]&#x7528;&#x4F8B;2&#x4E0D;&#x9700;&#x8981;&#x767B;&#x9646;,&#x76F4;&#x63A5;&#x64CD;&#x4F5C;two

test_mfixture.py::test_three            &#x8FD9;&#x4E2A;&#x662F;&#x767B;&#x9646;&#x529F;&#x80FD;&#xFF01;
PASSED                                  [100%]&#x7528;&#x4F8B;3&#x9700;&#x8981;&#x767B;&#x9646;,&#x7136;&#x540E;&#x64CD;&#x4F5C;three

============================== 3 passed in0.02s ==============================

&#x8FDB;&#x7A0B;&#x5DF2;&#x7ED3;&#x675F;&#xFF0C;&#x9000;&#x51FA;&#x4EE3;&#x7801; 0

-*- coding:utf-8 -*-
&#x4F5C;&#x8005;&#xFF1A;NoamaNelson
&#x65E5;&#x671F;&#xFF1A;2022/11/17
&#x6587;&#x4EF6;&#x540D;&#x79F0;&#xFF1A;test_mfixture.py
&#x4F5C;&#x7528;&#xFF1A;fixture&#x7684;&#x4F7F;&#x7528;
&#x8054;&#x7CFB;&#xFF1A;VX(NoamaNelson)
&#x535A;&#x5BA2;&#xFF1A;https://blog.csdn.net/NoamaNelson

import pytest

&#x4E0D;&#x5E26;&#x53C2;&#x6570;&#x65F6;&#x9ED8;&#x8BA4;scope="function"
@pytest.fixture
def case():
    print("&#x8FD9;&#x4E2A;&#x662F;&#x767B;&#x9646;&#x529F;&#x80FD;&#xFF01;")

def test_one(case):
    print("&#x7528;&#x4F8B;1&#x9700;&#x8981;&#x767B;&#x9646;,&#x7136;&#x540E;&#x8FDB;&#x884C;&#x64CD;&#x4F5C;one")

def test_two():
    print("&#x7528;&#x4F8B;2&#x4E0D;&#x9700;&#x8981;&#x767B;&#x9646;,&#x76F4;&#x63A5;&#x64CD;&#x4F5C;two")

@pytest.fixture
def case1():
    print("&#x8F93;&#x5165;&#x9A8C;&#x8BC1;&#x7801;")

def test_three(case):
    print("&#x7528;&#x4F8B;3&#x9700;&#x8981;&#x767B;&#x9646;,&#x7136;&#x540E;&#x64CD;&#x4F5C;three")

@pytest.mark.usefixtures("case", "case1")
def test_four(case1):
    print("&#x5148;&#x767B;&#x5F55;&#xFF0C;&#x518D;&#x8F93;&#x5165;&#x9A8C;&#x8BC1;&#x7801;&#xFF0C;&#x6700;&#x540E;&#x64CD;&#x4F5C;four")

if __name__ == "__main__":
    pytest.main(["-s", "test_mfixture.py"])

test_mfixture.py::test_one                    &#x8FD9;&#x4E2A;&#x662F;&#x767B;&#x9646;&#x529F;&#x80FD;&#xFF01;
PASSED                                        [ 25%]&#x7528;&#x4F8B;1&#x9700;&#x8981;&#x767B;&#x9646;,&#x7136;&#x540E;&#x8FDB;&#x884C;&#x64CD;&#x4F5C;one

test_mfixture.py::test_two PASSED             [ 50%]&#x7528;&#x4F8B;2&#x4E0D;&#x9700;&#x8981;&#x767B;&#x9646;,&#x76F4;&#x63A5;&#x64CD;&#x4F5C;two

test_mfixture.py::test_three                  &#x8FD9;&#x4E2A;&#x662F;&#x767B;&#x9646;&#x529F;&#x80FD;&#xFF01;
PASSED                                        [ 75%]&#x7528;&#x4F8B;3&#x9700;&#x8981;&#x767B;&#x9646;,&#x7136;&#x540E;&#x64CD;&#x4F5C;three

test_mfixture.py::test_four                   &#x8FD9;&#x4E2A;&#x662F;&#x767B;&#x9646;&#x529F;&#x80FD;&#xFF01;
                                              &#x8F93;&#x5165;&#x9A8C;&#x8BC1;&#x7801;
PASSED                                       [100%]&#x5148;&#x767B;&#x5F55;&#xFF0C;&#x518D;&#x8F93;&#x5165;&#x9A8C;&#x8BC1;&#x7801;&#xFF0C;&#x6700;&#x540E;&#x64CD;&#x4F5C;four

============================== 4 passed in0.03s ==============================

&#x8FDB;&#x7A0B;&#x5DF2;&#x7ED3;&#x675F;&#xFF0C;&#x9000;&#x51FA;&#x4EE3;&#x7801; 0
-*- coding:utf-8 -*-
&#x4F5C;&#x8005;&#xFF1A;NoamaNelson
&#x65E5;&#x671F;&#xFF1A;2022/11/17
&#x6587;&#x4EF6;&#x540D;&#x79F0;&#xFF1A;test_mfixture.py
&#x4F5C;&#x7528;&#xFF1A;fixture&#x7684;&#x4F7F;&#x7528;
&#x8054;&#x7CFB;&#xFF1A;VX(NoamaNelson)
&#x535A;&#x5BA2;&#xFF1A;https://blog.csdn.net/NoamaNelson

import pytest

&#x4E0D;&#x5E26;&#x53C2;&#x6570;&#x65F6;&#x9ED8;&#x8BA4;scope="function"
@pytest.fixture
def case():
    print("&#x8FD9;&#x4E2A;&#x662F;&#x767B;&#x9646;&#x529F;&#x80FD;&#xFF01;")

def test_one(case):
    print("&#x7528;&#x4F8B;1&#x9700;&#x8981;&#x767B;&#x9646;,&#x7136;&#x540E;&#x8FDB;&#x884C;&#x64CD;&#x4F5C;one")

def test_two():
    print("&#x7528;&#x4F8B;2&#x4E0D;&#x9700;&#x8981;&#x767B;&#x9646;,&#x76F4;&#x63A5;&#x64CD;&#x4F5C;two")

@pytest.fixture
def case1():
    print("&#x8F93;&#x5165;&#x9A8C;&#x8BC1;&#x7801;")

def test_three(case):
    print("&#x7528;&#x4F8B;3&#x9700;&#x8981;&#x767B;&#x9646;,&#x7136;&#x540E;&#x64CD;&#x4F5C;three")

@pytest.mark.usefixtures("case", "case1")
def test_four(case1):
    print("&#x5148;&#x767B;&#x5F55;&#xFF0C;&#x518D;&#x8F93;&#x5165;&#x9A8C;&#x8BC1;&#x7801;&#xFF0C;&#x6700;&#x540E;&#x64CD;&#x4F5C;four")

@pytest.fixture(autouse=True)
def case2():
    print("&#x6240;&#x6709;&#x7528;&#x4F8B;&#x90FD;&#x4F1A;&#x8C03;&#x7528;case2")

if __name__ == "__main__":
    pytest.main(["-s", "test_mfixture.py"])

test_mfixture.py::test_one                    &#x6240;&#x6709;&#x7528;&#x4F8B;&#x90FD;&#x4F1A;&#x8C03;&#x7528;case2
                                              &#x8FD9;&#x4E2A;&#x662F;&#x767B;&#x9646;&#x529F;&#x80FD;&#xFF01;
PASSED                                        [ 25%]&#x7528;&#x4F8B;1&#x9700;&#x8981;&#x767B;&#x9646;,&#x7136;&#x540E;&#x8FDB;&#x884C;&#x64CD;&#x4F5C;one

test_mfixture.py::test_two                    &#x6240;&#x6709;&#x7528;&#x4F8B;&#x90FD;&#x4F1A;&#x8C03;&#x7528;case2
PASSED                                        [ 50%]&#x7528;&#x4F8B;2&#x4E0D;&#x9700;&#x8981;&#x767B;&#x9646;,&#x76F4;&#x63A5;&#x64CD;&#x4F5C;two

test_mfixture.py::test_three                  &#x6240;&#x6709;&#x7528;&#x4F8B;&#x90FD;&#x4F1A;&#x8C03;&#x7528;case2
                                              &#x8FD9;&#x4E2A;&#x662F;&#x767B;&#x9646;&#x529F;&#x80FD;&#xFF01;
PASSED                                        [ 75%]&#x7528;&#x4F8B;3&#x9700;&#x8981;&#x767B;&#x9646;,&#x7136;&#x540E;&#x64CD;&#x4F5C;three

test_mfixture.py::test_four                   &#x6240;&#x6709;&#x7528;&#x4F8B;&#x90FD;&#x4F1A;&#x8C03;&#x7528;case2
                                              &#x8FD9;&#x4E2A;&#x662F;&#x767B;&#x9646;&#x529F;&#x80FD;&#xFF01;
                                              &#x8F93;&#x5165;&#x9A8C;&#x8BC1;&#x7801;
PASSED                                       [100%]&#x5148;&#x767B;&#x5F55;&#xFF0C;&#x518D;&#x8F93;&#x5165;&#x9A8C;&#x8BC1;&#x7801;&#xFF0C;&#x6700;&#x540E;&#x64CD;&#x4F5C;four

============================== 4 passed in0.03s ==============================

&#x8FDB;&#x7A0B;&#x5DF2;&#x7ED3;&#x675F;&#xFF0C;&#x9000;&#x51FA;&#x4EE3;&#x7801; 0

4.2 总结

  • 类前加 @pytest.mark.usefixtures() ,代表类里面所有测试用例都会调用该fixture
  • 可叠加多个 @pytest.mark.usefixtures() ,先执行的放底层,后执行的放上层
  • 可以传多个fixture参数,先执行的放前面,后执行的放后面
  • 如果fixture有返回值,用 @pytest.mark.usefixtures() 是无法获取到返回值的,必须用传参的方式
  • 不是test开头,加了装饰器也不会执行fixture。
    pytest学习和使用-fixture如何使用?

Original: https://blog.csdn.net/wx17343624830/article/details/128307758
Author: 爱吃 香菜
Title: pytest学习和使用-fixture如何使用?

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/774959/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • pandas pd.read_excel ()

    pd.read_excel () 首先,认识一下pd.read_excel(),函数的官方文档是这么说的: 将Excel文件读取到pandas DataFrame中,支持本地文件系…

    Python 2023年8月8日
    029
  • Python 引入模块的四种方法(超详细)

    注入产生的原理: 数据库设置为GBK编码: 宽字节注入源于程序员设置MySQL连接时错误配置为:set character_set_client=gbk,这样配置会引发编码转换从而…

    Python 2022年12月24日
    0101
  • HTML教程①-人人都懂的HTML基础知识

    HTML系列: 人人都懂的HTML基础知识-HTML教程 HTML元素大全(1) HTML元素大全(2)-表单 CSS系列: CSS基础知识筑基 常用CSS样式属性 CSS选择器大…

    Python 2023年10月18日
    041
  • Python数据分析 4.pandas数据科学库

    注入产生的原理: 数据库设置为GBK编码: 宽字节注入源于程序员设置MySQL连接时错误配置为:set character_set_client=gbk,这样配置会引发编码转换从而…

    Python 2022年12月29日
    0119
  • 用python正则表达式提取字符串

    注入产生的原理: 数据库设置为GBK编码: 宽字节注入源于程序员设置MySQL连接时错误配置为:set character_set_client=gbk,这样配置会引发编码转换从而…

    Python 2022年8月14日
    0239
  • Python将数据写入文本

    Python将数据写入文本,目前遇到的是处理两种数据,一种是对string类型的数据写入,还有一种是对数组类型的数据进行写入 1.对string类型的内容进行写入 创建文件对象我们…

    Python 2023年8月3日
    032
  • Python代码阅读(第41篇):矩阵转置

    注入产生的原理: 数据库设置为GBK编码: 宽字节注入源于程序员设置MySQL连接时错误配置为:set character_set_client=gbk,这样配置会引发编码转换从而…

    Python 2022年11月10日
    0154
  • pytest框架–pytest前置和后置

    注入产生的原理: 数据库设置为GBK编码: 宽字节注入源于程序员设置MySQL连接时错误配置为:set character_set_client=gbk,这样配置会引发编码转换从而…

    Python 2023年1月17日
    081
  • 【机器学习】支持向量机分类

    前言 支持向量机是一类按监督学习方式对数据进行二元分类的广义线性分类器,其决策边界是对学习样本求解的最大边距超平面。SVM尝试寻找一个最优决策边界,使距离两个类别最近的样本最远。S…

    Python 2023年11月2日
    023
  • 畸变校正与极线校正(具体原理+Matlab代码)

    注入产生的原理: 数据库设置为GBK编码: 宽字节注入源于程序员设置MySQL连接时错误配置为:set character_set_client=gbk,这样配置会引发编码转换从而…

    Python 2023年2月2日
    0156
  • Pytest如何对捕获的异常的类型和内容进行断言

    对捕获的异常进行断言主要用于在比如异常测试时,当我们给定了特殊的数据时,程序如果产生了我们期望的异常那么对测试而言是正确的,此时就可以通过对捕获的异常类型进行断言,当然对捕获的异常…

    Python 2023年9月11日
    015
  • ChatGPT体验和教程

    注入产生的原理: 数据库设置为GBK编码: 宽字节注入源于程序员设置MySQL连接时错误配置为:set character_set_client=gbk,这样配置会引发编码转换从而…

    Python 2023年2月5日
    0105
  • day01-Tomcat框架分析

    注入产生的原理: 数据库设置为GBK编码: 宽字节注入源于程序员设置MySQL连接时错误配置为:set character_set_client=gbk,这样配置会引发编码转换从而…

    Python 2023年1月29日
    060
  • 《利用Python进行数据分析》第七章——数据清洗与准备2

    在经过上文章对数据的缺失值进行过滤和补全,下面讲数据的一些转换,主要讲解数据的重新排列、过滤以及其他转换是另外一系列重要的操作。 1.1 删除重复值 当DataFrame出现重复行…

    Python 2023年8月7日
    043
  • 云原生时代必须具备的核心技能之Docker高级篇(DockerCompose-容器编排)

    ; 1 DockerCompose介绍 Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有…

    Python 2023年8月15日
    034
  • Pytorch保存和加载模型(load和load_state_dict)

    注入产生的原理: 数据库设置为GBK编码: 宽字节注入源于程序员设置MySQL连接时错误配置为:set character_set_client=gbk,这样配置会引发编码转换从而…

    Python 2022年8月28日
    0298
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球