博客
关于我
【pytest官方文档】解读fixtures - 9. 什么样的fixture结构,用起来最可靠?
阅读量:448 次
发布时间:2019-03-06

本文共 4110 字,大约阅读时间需要 13 分钟。

Pytest Fixture的不可靠性及优化实践

Pytest fixture是一种强大的工具,广泛应用于测试场景下的资源管理和环境准备工作。然而,尽管其功能强大, fixture 函数在实际应用中也存在一些潜在的问题。通过本文,我们将深入探讨这些问题,并提出相应的优化方案。

一、Fixture 函数的不可靠性

在使用 Pytest fixture 的过程中,最常见的问题是其不可靠性,主要体现在以下几个方面:

  • Fixture 函数名称缺乏描述性

    例如,命名为 setup 的 fixture 函数,虽然简洁,但并未能明确表达其具体功能,导致维护和阅读难度增加。

  • Fixture 函数操作复杂

    如果一个 fixture 函数包含多个操作步骤,尤其是涉及资源创建和管理的操作,往往会导致代码冗余,难以复用。

  • Yield 之前的操作一旦出错,teardown 就不会执行

    这是最严重的问题之一。例如,如果在 yield 之前创建的资源未能正确生成,teardown 操作就不会执行,导致资源未能被清理,进而引发后续测试用例的异常。

  • 二、Fixture 函数的优化实践

    为了解决上述问题,我们可以采取以下优化措施:

    1.Official Example 1: 分解Fixture 函数

    以下是一个经典的优化示例,展示了如何将复杂操作分解为多个独立的 fixture 函数:

    import pytestfrom emaillib import Email, MailAdminClient@pytest.fixturedef mail_admin():    return MailAdminClient()@pytest.fixturedef sending_user(mail_admin):    user = mail_admin.create_user()    yield user    mail_admin.delete_user(user)@pytest.fixturedef receiving_user(mail_admin):    user = mail_admin.create_user()    yield user    mail_admin.delete_user(user)def test_email_received(receiving_user, email):    email = Email(subject="Hey!", body="How's it going?")    sending_user.send_email(email, receiving_user)    assert email in receiving_user.inbox

    优化说明:

    • 每个 fixture 函数专注于单一功能,例如 mail_admin 只负责创建管理员客户端。
    • 通过参数传递,实现 fixture 函数之间的依赖关系,确保资源管理的透明性。
    • teardown 操作通过 yield 之后的清理代码自动执行,避免因错误导致资源未能清理。

    2.Official Example 2: Web 自动化测试优化

    以下是一个 Web 自动化测试的优化示例,展示了如何在复杂场景中实现 fixture 函数的高效管理:

    from uuid import uuid4from urllib.parse import urljoinfrom selenium.webdriver import Chromeimport pytestfrom src.utils.pages import LoginPage, LandingPagefrom src.utils import AdminApiClientfrom src.utils.data_types import User@pytest.fixturedef admin_client(base_url, admin_credentials):    return AdminApiClient(base_url, **admin_credentials)@pytest.fixturedef user(admin_client):    _user = User(name="Susan", username=f"testuser-{uuid4()}", password="P4$$word")    admin_client.create_user(_user)    yield _user    admin_client.delete_user(_user)@pytest.fixturedef driver():    _driver = Chrome()    yield _driver    _driver.quit()@pytest.fixturedef login(driver, base_url, user):    driver.get(urljoin(base_url, "/login"))    page = LoginPage(driver)    page.login(user)@pytest.fixturedef landing_page(driver, login):    return LandingPage(driver)def test_name_on_landing_page_after_login(landing_page, user):    assert landing_page.header == f"Welcome, {user.name}!"

    优化说明:

    • admin_clientuser fixture 函数通过参数传递,实现了资源的灵活管理。
    • driver fixture 函数负责浏览器的启动与退出,确保测试环境的清理。
    • 通过分解资源管理任务,实现了 fixture 函数的高度复用性和可靠性。

    3.My Practical Code示例

    以下是基于实际项目中的优化示例,展示了如何在复杂场景中实现 fixture 函数的高效管理:

    @pytest.fixturedef insert_sm_purchase_order():    """插入采购订单表的数据"""    db = DB("db_info")    purchase_order_sn = "CGN016" + deal_date() + str(random_int(4))    purchase_order_id = db.get_table_usable_latest_id("tcwms", "sm_purchase_order")    insert_sql = """INSERT INTO `tcw` ..."""    db.exec_sql(insert_sql)    db.close()    yield purchase_order_id, purchase_order_sn    db = DB("db_info")    db.exec_sql("DELETE FROM `tcw` ...")    db.close()@pytest.fixturedef insert_sm_purchase_order_goods(insert_sm_purchase_order):    """插入采购商品表的数据"""    db = DB("db_info")    purchase_order_goods_id = db.get_table_usable_latest_id("tcwms", "sm_purchase_order_goods")    po_id = insert_sm_purchase_order[0]    purchase_order_sn = insert_sm_purchase_order[1]    insert_sql = """INSERT INTO `tcw` ..."""    db.exec_sql(insert_sql)    db.close()    yield purchase_order_goods_id, po_id, purchase_order_sn    db = DB("tcwms_db_info")    db.exec_sql("DELETE FROM `tcw` ...")    db.close()

    优化说明:

    • insert_sm_purchase_orderinsert_sm_purchase_order_goods 分别负责主表和附属表的数据插入。
    • teardown 操作通过 yield 之后的清理代码自动执行,确保数据的完整性。
    • 通过参数传递,实现了 fixture 函数之间的资源共享和依赖管理。

    测试场景中的 fixture 函数优化

    为了更直观地理解 fixture 函数的优化效果,我们可以设计以下测试场景:

  • Fixture2 报错的情况

    • 如果 insert_sm_purchase_order_goods 在插入数据时发生错误,insert_sm_purchase_order 也会停止执行,避免数据不一致的问题。
  • Fixture1 报错的情况

    • 如果 insert_sm_purchase_order 在插入数据时发生错误,整个测试场景会自动回滚,确保环境不受污染。
  • 总结

    通过对 Pytest fixture 的深入分析,本文揭示了 fixture 函数在实际应用中的潜在问题,并提出了相应的优化方案。通过将复杂操作分解为多个独立的 fixture 函数,实现了资源管理的透明性和可靠性。同时,通过合理的测试场景设计,验证了优化效果的有效性。在实际项目中,可以根据具体需求继续对 fixture 函数进行优化和扩展,以满足更复杂的测试场景需求。

    转载地址:http://gkkfz.baihongyu.com/

    你可能感兴趣的文章
    Node.js 实现类似于.php,.jsp的服务器页面技术,自动路由
    查看>>
    node.js 怎么新建一个站点端口
    查看>>
    Node.js 文件系统的各种用法和常见场景
    查看>>
    node.js 简易聊天室
    查看>>
    node.js 配置首页打开页面
    查看>>
    node.js+react写的一个登录注册 demo测试
    查看>>
    Node.js中环境变量process.env详解
    查看>>
    Node.js卸载超详细步骤(附图文讲解)
    查看>>
    Node.js安装与配置指南:轻松启航您的JavaScript服务器之旅
    查看>>
    Node.js安装及环境配置之Windows篇
    查看>>
    Node.js安装和入门 - 2行代码让你能够启动一个Server
    查看>>
    node.js安装方法
    查看>>
    Node.js的循环与异步问题
    查看>>
    Node.js高级编程:用Javascript构建可伸缩应用(1)1.1 介绍和安装-安装Node
    查看>>
    NodeJS @kubernetes/client-node连接到kubernetes集群的方法
    查看>>
    Nodejs express 获取url参数,post参数的三种方式
    查看>>
    nodejs http小爬虫
    查看>>
    nodejs libararies
    查看>>
    nodejs npm常用命令
    查看>>
    NodeJS 导入导出模块的方法( 代码演示 )
    查看>>