You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何重构pytest测试用例中的公共代码段?

重构pytest测试用例公共代码的可行方案

针对你提到的「widget名称冗长,不想逐个解包变量」的问题,这里有几种更优雅的重构方式,无需依赖额外第三方库,都是Python/pytest内置或原生支持的方案:

方案1:用命名元组封装(推荐)

通过collections.namedtuple把所有widget打包成一个可通过属性访问的对象,不用在测试用例里挨个解包一堆变量:

from collections import namedtuple

# 用你的widget实际名称定义字段
ComponentWidgets = namedtuple('ComponentWidgets', [
    'user_profile_display_widget',
    'system_notification_bell_widget',
    'global_settings_menu_widget',
    # 其他widget名称...
])

def get_component_widgets(mock_app):
    # 提取各个widget的逻辑
    user_profile = mock_app.find_element("user-profile")
    notification_bell = mock_app.find_element("notification-bell")
    settings_menu = mock_app.find_element("settings-menu")
    # ...其他widget的提取逻辑
    
    # 顺便在这里完成公共的默认状态断言
    assert user_profile.is_enabled()
    assert notification_bell.has_no_unread()
    
    return ComponentWidgets(
        user_profile_display_widget=user_profile,
        system_notification_bell_widget=notification_bell,
        global_settings_menu_widget=settings_menu,
        # 对应字段赋值
    )

def test_component_feature_1(mock_app):
    widgets = get_component_widgets(mock_app)
    # 直接通过属性名访问目标widget,不用解包所有变量
    widgets.system_notification_bell_widget.activate()
    # 断言其他组件状态
    assert widgets.user_profile_display_widget.is_disabled()

方案2:用pytest fixture复用(最贴合pytest生态)

把提取widget+默认断言的逻辑做成pytest fixture,直接注入到测试用例中,彻底消除测试用例里的重复代码:

import pytest
from collections import namedtuple

ComponentWidgets = namedtuple('ComponentWidgets', [
    'user_profile_display_widget',
    'system_notification_bell_widget',
    'global_settings_menu_widget',
])

@pytest.fixture
def component_widgets(mock_app):
    # 提取widget
    user_profile = mock_app.find_element("user-profile")
    notification_bell = mock_app.find_element("notification-bell")
    settings_menu = mock_app.find_element("settings-menu")
    
    # 公共默认状态断言
    assert user_profile.is_enabled()
    assert notification_bell.has_no_unread()
    assert settings_menu.is_collapsed()
    
    return ComponentWidgets(
        user_profile_display_widget=user_profile,
        system_notification_bell_widget=notification_bell,
        global_settings_menu_widget=settings_menu,
    )

def test_component_feature_1(component_widgets):
    # 直接使用fixture注入的widget对象
    component_widgets.system_notification_bell_widget.activate()
    assert component_widgets.user_profile_display_widget.is_disabled()

def test_component_feature_2(component_widgets):
    component_widgets.global_settings_menu_widget.expand()
    assert component_widgets.system_notification_bell_widget.is_hidden()

方案3:自定义类封装(扩展性更强)

如果后续需要给widget集合添加通用操作(比如批量重置状态),可以自定义一个类来封装:

import pytest

class ComponentWidgets:
    def __init__(self, mock_app):
        # 初始化时提取所有widget
        self.user_profile_display_widget = mock_app.find_element("user-profile")
        self.system_notification_bell_widget = mock_app.find_element("notification-bell")
        self.global_settings_menu_widget = mock_app.find_element("settings-menu")
        # 自动执行默认状态断言
        self._assert_default_states()
    
    def _assert_default_states(self):
        assert self.user_profile_display_widget.is_enabled()
        assert self.system_notification_bell_widget.has_no_unread()
        assert self.global_settings_menu_widget.is_collapsed()
    
    # 可添加通用方法,比如重置所有widget
    def reset_all(self):
        self.user_profile_display_widget.reset()
        self.system_notification_bell_widget.reset()
        self.global_settings_menu_widget.reset()

@pytest.fixture
def component_widgets(mock_app):
    return ComponentWidgets(mock_app)

def test_component_feature_3(component_widgets):
    component_widgets.global_settings_menu_widget.expand()
    assert component_widgets.system_notification_bell_widget.is_hidden()
    # 使用通用重置方法
    component_widgets.reset_all()
    assert component_widgets.global_settings_menu_widget.is_collapsed()

内容的提问来源于stack exchange,提问作者Olumide

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 15:06:11