"二戰" UI 測試 之 代碼設計

背景

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

  1. 初始化 base_actions_map,也就是咱們的基礎操做字典,咱們要在這裏對全部的測試執行步驟和對應的執行函數進行映射。orm

  2. 實現 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 自動化測試中得到正收益,但測試技術的發展永無止境~

相關文章
相關標籤/搜索