如何重构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
相关产品推荐
相关产品推荐

