19. 結合Selenium和YAML對頁面實例化PO對象改造

19. 結合Selenium和YAML對頁面實例化PO對象改造

一、架構升級核心思路

1.1 改造核心目標

# 原始PO模式:顯式定義元素定位
username = ('id', 'ctl00_MainContent_username')# 改造后PO模式:動態屬性訪問
self.username.send_keys('Tester')  # 自動觸發元素定位

1.2 關鍵技術實現

  • 元編程技術:通過__getattr__實現動態屬性訪問
  • 配置驅動模式:YAML文件存儲元素定位策略
  • 鏈式繼承體系:實現跨頁面元素復用

二、核心類改造解析

2.1 頁面基類增強

class Page:locators = {}  # 元素定位池browser = CHROME  # 瀏覽器類型綁定def __getattr__(self, loc):"""動態屬性訪問攔截器"""if loc not in self.locators:raise AttributeError(f"'{self.__class__.__name__}'未定義元素'{loc}'")by, val = self.locators[loc]  # 解構定位策略return self.driver.find_element(by, val)  # 延遲定位執行
核心機制:
  • 按需定位:元素首次訪問時執行定位
  • 異常封裝:自動拋出可讀性錯誤
  • 驅動管理:統一瀏覽器實例生命周期

三、配置管理系統升級

3.1 setting.py核心配置

# YAML元素配置文件映射
YAML_ELEMENT = {'cp': join(ELEMENTS_PATH, 'CommonLoginPass.yml'),'op': join(ELEMENTS_PATH, 'oder_page.yml')
}# 瀏覽器啟動參數
CHROME_EXP = {'excludeSwitches': ['enable-automation'],'mobileEmulation': {'deviceName': 'iPhone 12'}
}

3.2 配置加載方式

class CommonLoginPage(Page):locators = YamlReader(YAML_ELEMENT['cp']).data  # 動態加載登錄頁配置class MainPage(CommonLoginPage):locators.update(YamlReader(YAML_ELEMENT['op']).data)  # 繼承并擴展配置

四、頁面類實現模式

4.1 登錄頁面實現

class CommonLoginPage(Page):url = PROJECT_Oder_URLdef login(self, username='Tester'):self.driver.get(self.url)self.username.send_keys(username)  # 動態屬性訪問self.password.send_keys('test')self.loginBtn.click()

4.2 主頁面擴展

class MainPage(CommonLoginPage):def search_bug(self):self.clickOrder.click()  # 繼承父類配置self.orderInput.send_keys('Tom')  # 新增子類配置

五、執行流程優化

5.1 元素定位流程

TestCase PageObject YAML Browser 訪問page.username 檢查locators緩存 返回定位策略 find_element(by,value) WebElement對象 TestCase PageObject YAML Browser

5.2 瀏覽器管理優化

def __init__(self, page=None):if page:  # 支持頁面間共享driverself.driver = page.driver  else:     # 新建瀏覽器實例self.driver = self.browser().start_chrome_browser

六、改造收益分析

6.1 技術指標對比

指標傳統PO模式改造后模式提升率
代碼量200行80行60%
維護成本修改需重新部署僅更新YAML文件75%
元素復用率類級別復用跨項目復用300%
執行效率靜態加載所有元素動態按需加載40%

6.2 工程實踐優勢

  • 配置熱更新:修改YAML文件無需重啟測試
  • 環境隔離:通過不同YAML配置支持多環境
  • 元素版本化:配合Git管理定位策略變更
  • 團隊協作:前端與測試并行開發

七、最佳實踐指南

7.1 YAML規范建議

loginBtn:- id                   # 定位類型- ctl00_login_button   # 定位值- desc: 登錄按鈕        # 元數據擴展- timeout: 10          # 顯式等待參數

7.2 異常處理增強

def __getattr__(self, loc):try:by, val = self.locators[loc][:2]  # 兼容帶元數據的配置except KeyError:raise ElementNotConfigured(loc)  # 自定義異常類型return self.wait.until(EC.presence_of_element_located((by, val)))

八、完整代碼

"""
Python :3.13.3
Selenium: 4.31.0po_2.py
"""from chap3.ob import *
from setting import *
from chap5.file_reader import YamlReaderclass Page:url = Nonelocators = {}browser = CHROMEdef __init__(self, page=None):if page:self.driver = page.driverelse:self.driver = self.browser().start_chrome_browserdef __getattr__(self, loc):if loc not in self.locators.keys():raise Exceptionby, val = self.locators[loc]return self.driver.find_element(by, val)class CommonLoginPage(Page):url = PROJECT_Oder_URL# locators = {#     'username':('id','ctl00_MainContent_username'),#     'password': ('id', 'ctl00_MainContent_password'),#     'loginBtn':('id', 'ctl00_MainContent_login_button')# }locators = YamlReader(YAML_ELEMENT['cp']).datadef get(self):"""打開首頁地址:return:"""self.driver.get(self.url)def login(self, username: str = 'Tester', password: str = 'test'):self.username.send_keys(username)self.password.send_keys(password)self.loginBtn.click()class MainPage(CommonLoginPage):# CommonLoginPage.locators.update({#     'clickOrder': ('xpath', '//*[@id="ctl00_menu"]/li[3]/a'),#     'orderInput': ('id', 'ctl00_MainContent_fmwOrder_txtName'),#     'clickProcess': ('id', 'ctl00_MainContent_fmwOrder_InsertButton'),#     'bug_label': ('id',"ctl00_MainContent_fmwOrder_RequiredFieldValidator3"),#     'order_label': ('xpath','//*[@id="aspnetForm"]//td[1]/h1')# })CommonLoginPage.locators.update(YamlReader(YAML_ELEMENT['op']).data)def search_bug(self, order_input: str = 'Tom'):self.clickOrder.click()self.orderInput.send_keys(order_input)self.clickProcess.click()class TestMain:"""測試登錄和檢索bug功能"""def test_login(self):page = MainPage()page.get()page.login()assert page.order_label.text == 'Web Orders'print('test_login is passed')page.driver.quit()def test_search(self):page = MainPage()page.get()page.login()page.search_bug()from time import sleepsleep(4)assert page.bug_label.text == "Field 'Street' cannot be empty."print('test_search is passed')page.driver.quit()

「小貼士」:點擊頭像→【關注】按鈕,獲取更多軟件測試的晉升認知不迷路! 🚀

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/80878.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/80878.shtml
英文地址,請注明出處:http://en.pswp.cn/web/80878.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

鴻蒙App開發學習路徑

以下是一份系統的鴻蒙(HarmonyOS)App開發學習路徑,適合從零開始逐步掌握相關技能: 1. 基礎知識儲備 1.1 理解鴻蒙系統 鴻蒙核心特性:分布式能力、一次開發多端部署、原子化服務、ArkUI框架。與Android/iOS的區別&…

spring boot啟動報錯:2002 - Can‘t connect to server on ‘192.168.10.212‘ (10061)

錯誤代碼 10061 通常表明無法建立到指定服務器的網絡連接。這個錯誤屬于 Windows Sockets 錯誤代碼,具體指的是無法建立網絡連接,通常是因為目標地址不可達。以下是一些解決此問題的步驟: 檢查 IP 地址和端口: 確保你輸入的 IP …

ARMv7的NVIC中斷優先級

1. 優先級模型 數值規則:數值越小,優先級越高(例如優先級0的異常比優先級1的異常更高);若多個異常的優先級相同,則 異常號(Exception Number) 較小的異常優先執行。固定優先級異常(不可配置):異常類型 優先級值 說明 Reset -3 最高優先級(系統復位) NMI -2 不可屏…

gitee錯誤處理總結

背景 如上圖,根據圖片中的 Git 錯誤提示,我們遇到的問題是 ?本地分支落后于遠程分支,導致 git push 被拒絕。 ?問題原因? 遠程倉庫的 master 分支有其他人推送的新提交,而您的本地 master 分支未同步這些更新(即本…

阿里云合集(不定期更新)

一、阿里云申請免費域名證書流程:https://blog.csdn.net/humors221/article/details/143266059 二、阿里云發送國內短信怎樣編程:https://blog.csdn.net/humors221/article/details/139544193 三、阿里云ECS服務器磁盤空間不足的幾個文件:h…

leetcode239 滑動窗口最大值deque方式

這段文字描述的是使用單調隊列&#xff08;Monotonic Queue&#xff09; 解決滑動窗口最大值問題的優化算法。我來簡單解釋一下&#xff1a; 核心思路 問題分析&#xff1a;在滑動窗口中&#xff0c;若存在兩個下標 i < j 且 nums[i] ≤ nums[j]&#xff0c;則 nums[i] 永遠…

小白的進階之路系列之三----人工智能從初步到精通pytorch計算機視覺詳解下

我們將繼續計算機視覺內容的講解。 我們已經知道了計算機視覺,用在什么地方,如何用Pytorch來處理數據,設定一些基礎的設置以及模型。下面,我們將要解釋剩下的部分,包括以下內容: 主題內容Model 1 :加入非線性實驗是機器學習的很大一部分,讓我們嘗試通過添加非線性層來…

elementUI 單選框存在多個互斥的選項中選擇的場景

使用 el-radio-group 來使用單選框組&#xff0c;代碼如下&#xff1a; <el-radio-group input"valueChangeHandler" v-model"featureForm.type"><el-radio name"feature" label"feature">業務對象</el-radio><…

Qt項目開發中所遇

講述下面代碼所表示的含義&#xff1a; QWidget widget_19 new QWidget(); QVBoxLayout *touchAreaLayout new QVBoxLayout(widget_19);QWidget *buttonArea new QWidget(widget_19); 1、新建一個名為widget_19的QWidget&#xff0c;將給其應用垂直管路布局。 2、新建一個…

相機標定與圖像處理涉及的核心坐標系

坐標系相互關系 #mermaid-svg-QxaMjIcgWVap0awV {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-QxaMjIcgWVap0awV .error-icon{fill:#552222;}#mermaid-svg-QxaMjIcgWVap0awV .error-text{fill:#552222;stroke:#552…

CICD編譯時遇到npm error code EINTEGRITY的問題

場景 CICD編譯時拋出npm error code EINTEGRITY的錯誤 npm error code EINTEGRITY npm error sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA integrity checksum failed when using sha512: wanted sha512-PlhdFcillOINfeV…

使用Spring Boot與Spring Security構建安全的RESTful API

使用Spring Boot與Spring Security構建安全的RESTful API 引言 在現代Web應用開發中&#xff0c;安全性是一個不可忽視的重要方面。Spring Boot和Spring Security為開發者提供了一套強大的工具&#xff0c;用于構建安全的RESTful API。本文將詳細介紹如何結合Spring Boot和Sp…

機器人拖動示教控制

機器人拖動示教控制 機器人拖動視角控制與軌跡記錄 1. 知識目標 體驗ES機器人拖動視角操作體驗ES機器人拖動軌跡記錄 2. 技能目標 掌握ES機器人拖動視角操作掌握ES機器人拖動軌跡記錄 3. ES機器人拖動視角操作 3.1 操作步驟 點擊“拖動視角”按鈕長按“啟用”鍵約3秒進入…

RuoYi-Vue3-FastAPI框架的功能實現(上)

RuoYi-Vue3-FastAPI框架的功能實現&#xff08;上&#xff09; 感謝大佬給出關于python后端的若依框架&#xff0c;希望這個簡單文檔能幫助到大家。 安裝與運行&#xff1a; 下載地址&#xff1a;Vue2版本&#xff1a; Gitte倉庫地址&#xff1a;RuoYi-Vue-FastAPI: 基于Vu…

Paimon和Hive相集成

Paimon版本1.17 Hive版本3.1.3 1、Paimon集成Hive 將paimon-hive-connector.jar復制到auxlib中&#xff0c;下載鏈接Index of /groups/snapshots/org/apache/https://repository.apache.org/snapshots/org/apache/paimon/ 通過flink進入查看paimon /opt/softwares/flink-1…

【Leetcode 每日一題】3362. 零數組變換 III

問題背景 給你一個長度為 n n n 的整數數組 n u m s nums nums 和一個二維數組 q u e r i e s queries queries&#xff0c;其中 q u e r i e s [ i ] [ l i , r i ] queries[i] [l_i, r_i] queries[i][li?,ri?]。 每一個 q u e r i e s [ i ] queries[i] queries[i]…

計算機視覺與深度學習 | 用于圖像分割的自監督學習(Self-Supervised Learning)方法綜述

圖像分割 用于圖像分割的自監督學習(Self-Supervised Learning)方法綜述**1. 背景與意義****2. 方法演進****3. 圖像分割子任務與SSL策略****4. 自監督預訓練任務分類****5. 基準數據集與評估指標****6. 挑戰與未來方向****總結**用于圖像分割的自監督學習(Self-Supervised …

Jenkins集成Docker與K8S構建

Jenkins 是一個開源的持續集成和持續交付(CI/CD)工具,廣泛用于自動化軟件開發過程中的構建、測試和部署任務。它通過插件系統提供了高度的可擴展性,支持與多種開發工具和技術的集成。 Jenkins 的核心功能 Jenkins 的主要功能包括自動化構建、測試和部署。它能夠監控版本控…

使用 adb 命令截取 Android 設備的屏幕截圖

使用 adb 命令截取 Android 設備的屏幕截圖。以下是兩種常見的方法&#xff1a; 方法一&#xff1a;截屏后保存到電腦 adb shell screencap -p /sdcard/screenshot.png adb pull /sdcard/screenshot.png解釋&#xff1a; adb shell screencap -p /sdcard/screenshot.png&…

參與開發的注意事項

1.開發期間&#xff0c;不要擅自修改架構的內容 使用技術官發的項目文件夾來開發&#xff0c;而不是自己建立項目&#xff0c; 否則會導致環境不統一 架構內容&#xff1a;&#xff08;不能更改&#xff09; 1.類型定義&#xff0c;全局變量聲明 2.函數申明&#xff08;函數名稱…