UI 自动化测试一直是老生常谈的话题,css
做为处于"金字塔顶端"的自动化手段,用的很差就是一场灾难,用的好也没法雪中送炭。markdown
在本篇文章中,我将记录一下我"第二次"设计 UI 测试的心得体会。架构
POM (页面对象模型)相信你们已经很是熟悉了,核心思想就是每一个页面对应一个类,在每一个类中放置页面中的定位信息以及相关操做函数。函数
然而在 POM 的基础上,咱们其实能够将每一个页面的操做抽象成字典映射。这样一来,全部的用例执行对应的操做会变得很是清晰。测试
self.actions_map = {
'点击职位管理标签': self._click_job_position_management_tab,
'点击新增职位按钮': self._click_add_job_position_button,
'输入职位信息': self._input_job_position_info,
}
复制代码
在实战中,也相信你们发现很多页面带有重复的元素,好比标签栏,导航栏等通用组件。spa
针对这个状况,咱们能够设计一个页面基础类,储存全部页面通用的 基础操做 与 通用定位,全部独立的页面类均可以继承这个基础类,从而使得代码架构变得更加整洁,有效减小重复代码。设计
class PageObjectModel:
LOCATORS = {
'el-message--success': {'css selector': '.el-message--success'},
'bread_crumb_nav': {'css selector': 'div[role=\'navigation\']'},
}
def __init__(self, browser=None):
self.browser = browser
self.actions_map = {}
self.base_actions_map = {
'检查并激活主页面包屑导航': self._check_and_activate_tab_bar,
'切换至新开窗口': self._switch_to_new_window,
'关闭当前窗口': self._close_current_window,
'关闭新开窗口': self._close_new_window,
}
def operate(self, action, **kwargs):
if action in self.actions_map.keys():
self.actions_map[action](**kwargs)
elif action in self.base_actions_map.keys():
self.base_actions_map[action](**kwargs)
else:
preporter.warn(msg=f'action: 【{action}】 不在 action_map 内!')
复制代码
这里的设计关键有两点:code
初始化 base_actions_map,也就是咱们的基础操做字典,咱们要在这里对全部的测试执行步骤和对应的执行函数进行映射。orm
实现 operate 方法,全部的用例执行操做步骤都将经过 operate 方法 优先 在自己的操做字典中寻找映射函数。对象
基础类设计完毕~。
假设咱们如今须要对某个页面作UI自动化,咱们的只须要继承刚刚实现 PageObjectModel, 而后构造 actions_map 就能够了~
class JobPositionManagement(PageObjectModel):
LOCATORS = {
# 职位管理列表页元素
'job_position_management_page': {'tag name': 'li', 'text': '职位管理'},
}
def __init__(self, browser=None):
super(JobPositionManagement, self).__init__(browser)
self.actions_map = {
'点击职位管理标签': self._click_job_position_management_tab,
}
def _click_job_position_management_tab(self, browser=None):
_browser = self.browser if self.browser else browser
_browser.v_click(locate_rule=self.LOCATORS['job_position_management_page'])
复制代码
最后在实际测试调用中,代码会变得很是整洁清晰,而这也是程序设计的魅力。
@HistoricalLogsDeletion
@Test(enabled=False, tags=["职位管理", "回归测试", "冒烟测试"], description="验证点击【生成JD】后,JD输入框是否生成数据", timeout=30)
def test_06(self):
self.job_position_management.operate(action='生成JD')
self.job_position_management.operate(action='等待页面加载完毕')
self.job_position_management.operate(action='验证JD输入框内是否存在数据')
复制代码
虽然大部分公司都没法成功在 UI 自动化测试中得到正收益,但测试技术的发展永无止境~