fixture

2023-12-24 01:52
文章标签 fixture

本文主要是介绍fixture,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

章节目录:

    • 一、概述
    • 二、参数列表
    • 三、通过 fixture 实现 setup 操作
      • 3.1 三种调用方式
      • 3.2 类声明调用
      • 3.3 叠加使用
      • 3.4 同时传多个参数
      • 3.5 获取 fixture 返回值
      • 3.6 fixture 依赖其他 fixture
    • 四、实例化顺序
    • 五、通过 fixture 实现 teardown 操作
      • 5.1 yield 实现 teardown
      • 5.2 yield + with 的结合
      • 5.3 addfinalizer 终结函数
    • 六、结束语

一、概述

fixture 是 pytest 框架提供的一个特性,用于管理测试中的资源和设定。它可以在测试函数或测试类中使用,以提供测试所需的固定数据、对象或执行特定的操作。

  • 与 setup 和 teardown 相比,fixture 提供了更灵活、可重用和可扩展的测试环境设置功能。
  • 特点和用法:
    • 灵活性fixture 可以在测试函数、测试类或整个测试模块级别使用,以满足不同的测试需求。
    • 可重用性fixture 可以在多个测试函数或测试类中共享,并可以在不同的测试模块中重复使用。
    • 参数化fixture 可以接受参数,以便在测试时动态生成或配置测试数据和资源。
    • 自动化:pytest 会自动检测并调用适用的 fixture,无需手动调用。

二、参数列表

import pytest@pytest.fixture(scope="function", params=None, autouse=False, ids=None, name=None)
def test():pass
  • scope:可以理解成 fixture 的作用域,默认:function,还有 class、module、package、session 四个。( session 是整个测试会话,即开始执行 pytest 到结束测试。)
  • autouse(默认):False,需要用例手动调用该 fixture;如果是 True,所有作用域内的测试用例都会自动调用该 fixture
  • name(默认):装饰器的名称,同一模块的 fixture 相互调用建议写个不同的 name。

三、通过 fixture 实现 setup 操作

3.1 三种调用方式

  • 方式一:通过名称入参调用
import pytest# 1.定义 fixture 。
@pytest.fixture
def login():data = {}print("\n登录完成!")# 返回测试数据或对象给测试函数使用。return datadef test_case_01():print("无需登录的测试操作。")# 2.通过 fixture 名称调用。
def test_case_02(login):print("需要登录才能进行的测试操作。")if __name__ == '__main__':pytest.main(["-s"])# [ 50%]无需登录的测试操作。## 登录完成!# [100%]需要登录才能进行的测试操作。
  • 方式二:测试用例加上装饰器 @pytest.mark.usefixtures(fixture_name)
import pytest@pytest.fixture
def login():data = {}print("\n登录完成!")return data# 1.再添加一个 fixture。
@pytest.fixture
def authentication():print("\n认证完成!")def test_case_01():print("无需登录的测试操作。")# 2.使用装饰器指定。
@pytest.mark.usefixtures("login", "authentication")
def test_case_02():print("需要登录并通过验证,才能进行的测试操作。")if __name__ == '__main__':pytest.main(["-s"])# [ 50%]无需登录的测试操作。## 登录完成!# 认证完成!# [100%]需要登录并通过验证,才能进行的测试操作。
  • 方式三:自动调用
import pytest# 1.设置自动应用到每个测试函数中。
@pytest.fixture(autouse=True)
def query_database():data = {}print("\n完成数据库查询!")return datadef test_case_01():print("执行测试用例一。")def test_case_02():print("执行测试用例二。")if __name__ == '__main__':pytest.main(["-s"])# 完成数据库查询!# [ 50%]执行测试用例一。## 完成数据库查询!# [100%]执行测试用例二。

3.2 类声明调用

  • 类声明上面加 @pytest.mark.usefixtures() ,代表这个类里面所有测试用例都会调用该 fixture
import pytest@pytest.fixture
def query_database():print("query_database")# 在类上面声明。(所有用例都调用。)
@pytest.mark.usefixtures("query_database")
class Tests:def test_case_01(self):print("test_case_01")def test_case_02(self):print("test_case_02")if __name__ == '__main__':pytest.main(["-s"])# query_database# [ 50%]test_case_01## query_database# [100%]test_case_02

3.3 叠加使用

  • 可以叠加多个 @pytest.mark.usefixtures() ,先执行的放底层,后执行的放上层:
import pytest@pytest.fixture
def query_database():print("query_database")@pytest.fixture
def authentication():print("authentication")# 叠加使用。(从下到上执行。)
@pytest.mark.usefixtures("query_database")
@pytest.mark.usefixtures("authentication")
def test_case_01():print("test_case_01")if __name__ == '__main__':pytest.main(["-s"])# authentication# query_database# [100%]test_case_01

3.4 同时传多个参数

  • @pytest.mark.usefixtures() 可以传多个 fixture 参数,先执行的放前面,后执行的放后面:
import pytest@pytest.fixture
def query_database():print("query_database")@pytest.fixture
def authentication():print("authentication")# 传多个参数。(从前到后执行。)
@pytest.mark.usefixtures("authentication", "query_database")
def test_case_01():print("test_case_01")if __name__ == '__main__':pytest.main(["-s"])# authentication# query_database# [100%]test_case_01

3.5 获取 fixture 返回值

  • 如果 fixture 有返回值,用 @pytest.mark.usefixtures() 是无法获取到返回值的,必须用传参的方式
import jsonimport pytest@pytest.fixture
def query_database():# mock 返回的数据。data = {"code": 0,"msg": "SUCCESS","user": {"name": "jan","age": 18}}print("query_database successes!")return json.dumps(data)# 1.装饰器无法获取返回值。
@pytest.mark.usefixtures("query_database")
def test_case_01():print("test_case_01")# 2.通过名称入参才能获取返回值。
def test_case_02(query_database):print("test_case_02 get res=", json.loads(query_database))if __name__ == '__main__':pytest.main(["-s"])# test_case_01# test_case_02 get res= {'code': 0, 'msg': 'SUCCESS', 'user': {'name': 'jan', 'age': 18}}

3.6 fixture 依赖其他 fixture

如果 fixture 还想依赖其他 fixture,需要用函数传参的方式,不能用 @pytest.mark.usefixtures() 的方式,否则会不生效。

  • 代码示例
import pytest@pytest.fixture(scope="session")
def open_browser():print("===打开浏览器===")# 1.依赖其他 fixture 。
@pytest.fixture
# 通过 @pytest.mark.usefixtures 调用不生效。
# @pytest.mark.usefixtures("open_browser")
# 需要通过名称入参。
def query_database(open_browser):print("===查询数据库===")def test_case_01(query_database):passif __name__ == '__main__':pytest.main(["-s"])# ===打开浏览器===# ===查询数据库===

四、实例化顺序

  • 根据 scope 范围实例化: session > package > module > class > function
  • 具有相同作用域的 fixture 遵循测试函数中声明的顺序,并遵循 fixture 之间的依赖关系。(在 fixture_A 里面依赖的 fixture_B ,则 fixture_B 优先实例化。)
  • 自动使用autouse=True)的 fixture 将在显式使用(传参或装饰器)的 fixture 之前实例化。

五、通过 fixture 实现 teardown 操作

5.1 yield 实现 teardown

fixture 需要搭配 yield 关键字来开启 teardown 操作。

  • yield 关键字用于定义一个生成器函数。

  • 生成器函数是一种特殊的函数,它不会像普通函数一样立即执行并返回一个结果,而是每次迭代时返回一个值,并在下一个迭代时从上次离开的位置继续执行

  • 通过使用 yield 关键字,生成器函数可以保存其状态,这使得它们在处理大量数据时非常高效。

  • 代码示例

import pytest@pytest.fixture(scope="session")
def open_browser():print("===打开浏览器===")yieldprint("===关闭浏览器===")@pytest.fixture
def query_database(open_browser):print("===开始查询数据库===")name = "jan"age = 18yield name, ageprint("===数据库查询完成===")def test_case_01(query_database):print("===执行测试用例1===")# 获取返回结果。print("返回:", query_database)name, age = query_database# 断言。assert "jan" == nameassert 18 == agedef test_case_02(query_database):print("===执行测试用例2===")if __name__ == '__main__':pytest.main(["-s"])# ===打开浏览器===## ===开始查询数据库===# PASSED ===执行测试用例1===# 返回: ('jan', 18)# ===数据库查询完成===## ===开始查询数据库===# PASSED ===执行测试用例2===# ===数据库查询完成===## ===关闭浏览器===
  • 如果 yield 前面的代码,即 setup 部分已经抛出异常了,则不会执行 yield 后面的 teardown 内容。
  • 如果测试用例抛出异常,yield 后面的 teardown 内容还是会正常执行。

5.2 yield + with 的结合

  • 官方示例
@pytest.fixture(scope="module")
def smtp_connection():with smtplib.SMTP("smtp.gmail.com", 587, timeout=5) as smtp_connection:yield smtp_connection  # provide the fixture value
  • smtp_connection() 连接将测试完成执行后已经关闭,因为 smtp_connection() 对象自动关闭时,with 语句结束。

5.3 addfinalizer 终结函数

  • 代码示例
import pytest@pytest.fixture(scope="module")
def open_browser(request):print("===打开浏览器===")def close_browser():print("===关闭浏览器===")# addfinalizer 将 close_browser 函数注册为终结器。request.addfinalizer(close_browser)def test_case_01(open_browser):print("===执行测试用例1===")def test_case_02(open_browser):print("===执行测试用例2===")if __name__ == '__main__':pytest.main(["-s"])# ===打开浏览器===# PASSED ===执行测试用例1===# PASSED ===执行测试用例2===# ===关闭浏览器===
  • 如果 request.addfinalizer() 前面的代码,即 setup 部分已经抛出异常了,则不会执行 request.addfinalizer() 的 teardown 内容。
  • 可以声明多个终结函数并调用。

六、结束语


“-------怕什么真理无穷,进一寸有一寸的欢喜。”

微信公众号搜索:饺子泡牛奶

这篇关于fixture的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/530197

相关文章

3 pytest Fixture

3 pytest Fixture 3.1 通过 conftest.py 共享 fixture3.2 使用 fixture 执行配置及销毁逻辑3.3 使用 --setup-show 回溯 fixture 的执行过程3.4 使用 fixture 传递测试数据3.5 使用多个 fixture3.6 指定 fixture 作用范围3.7 使用 usefixtures 指定 fixture3.8 为常

【Rust日报】2019-09-04 - retest一个基于 fixture 的rust测试框架

CPP工程师的Rust迁移之路 #rust #cpp 5.继承与组合 - 下4.继承与组合 - 中3.继承与组合 - 上2.类与结构体1.起步 Read More regex 1.3的改动 #rust #crate regex1.3允许禁用Unicode等影响性能的特性,这可以减少超过1MB的二进制文件大小,将编译时间缩短一半,并将依赖关系树减少到一个包。 我们可以从一个issue#613中了

pytest的fixture()函数中的参数详解

一、概述 在pytest测试框架中,@pytest.fixture()是一个非常重要的装饰器,它允许你定义一些在测试函数或测试类之间共享的设置和清理代码。这些设置和清理代码通常包括创建测试数据、设置测试环境、关闭数据库连接等。 二、参数解读 1.scope: 定义fixture的作用域。可能的值有:function(默认),class,module,package,session。 fu

通过pytest-xdist插件并发执行用例时, scope=session的fixture会运行多次问题的解决方案

场景 在UI自动化项目中,使用的是pytest + playwright, 需要实现同一个用户只登录一次的,所以在conftest.py中定义了一个scope=session的fixture,然后在此fixture中实现了系统登录,在非并发模式下执行的时候,能保证同一个用户只登录一次,但是并发执行的时候每个case都会执行登录 问题 需要解决并发执行的时候同一个用户只登录一次,如果是不同用户

一文弄懂Pytest——fixture用法

💟💟前言 ​ 友友们大家好,我是你们的小王同学😗😗 今天给大家打来的是 一文弄懂Pytest——fixture用法 希望能给大家带来有用的知识 觉得小王写的不错的话麻烦动动小手 点赞👍 收藏⭐ 评论📄 小王的主页:小王同学🚗 小王的gitee:小王同学🏩🏩 小王的github:小王同学💦 ​ 🎐什么是fixture?? ​ 在Python中,特别是在使用py

pytest 的 request fixture:实现个性化测试需求

在之前深入理解pytest-repeat插件的工作原理一文中,我们看到pytest_repeat源码中有这样一段 @pytest.fixture def __pytest_repeat_step_number(request):    marker = request.node.get_closest_marker("repeat")    count = marker and ma

【pytest】fixture机制

目录 概念fixture 的主要特点测试场景1. 准备和清理测试数据2. 模拟外部依赖3. 共享资源(如数据库连接)4. 使用内置 fixture5. 自动使用 fixture 用途 概念 fixture机制是pytest测试框架中的一个核心概念,它提供了一种用于处理测试所需资源的机制。通过fixture,你可以在测试函数之前或之后执行特定的代码,并返回一个值或对象供测试函数使

Pytest框架Fixture+Parametrize参数化应用篇

前面三节概要的讲述了Pytest框架Fixture应用以及Parametrize参数化应用,今天也拿实例列举进行将2个方法综合使用 Python自动化测试 | Pytest之参数化 Pytest | 参数化处理三种类型 [ 列表、元组、字典] Python自动化测试 | Pytest之fixture 就拿小编实际项目中的管理台登录界面测试作为案例,代码浅而易学,前半部分是Fixture,后半部分

pytest之fixture结合conftest.py文件使用+断言实战

pytest之fixture结合conftest.py文件使用 conftest.py--存放固件固件的优先级pytest执行流程pytest之断言实战pytest结合allure-pytest插件生成美观的报告 conftest.py–存放固件 在一个项目的测试中,大多数情况下会有多个类、模块、或者包要使用相同的测试夹具。这种情况下如果我们把测试夹具定义在某一个模块中则无法实

pytest教程-15-多个fixture以及重命名

领取资料,咨询答疑,请➕wei:  June__Go 上一小节我们学习了fixture的yield关键字,本小节我们讲解一下使用多个fixture的方法。 使用多个fixture 如果用例需要用到多个fixture的返回数据,fixture也可以return一个元组、list或字典,然后从里面取出对应数据。 #test_demo.pyimport pytest@pytest.fixtur