轉載請註明出處❤️
作者:IT小學生蔡坨坨
原文連結:五分鐘搞懂POM設計模式
大家好,我是IT小學生蔡坨坨。
今天,我們來聊聊Web UI自動化測試中的POM設計模式。
前期,我們學會了使用Python+Selenium編寫Web UI自動化測試線性指令碼
線性指令碼(以快遞100網站登入舉慄):
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("https://sso.kuaidi100.com/sso/v2/authorize.do")
driver.maximize_window()
driver.find_element(By.ID, 'name').send_keys("***********")
driver.find_element(By.ID, 'password').send_keys("***********")
driver.find_element(By.ID, 'submit').click()
time.sleep(2)
text = driver.find_element(By.PARTIAL_LINK_TEXT, '首頁').text
assert text == '首頁'
driver.close()
使用以上程式碼,最基礎最簡單的Web UI 自動化測試就做起來了,但是,問題也隨之而來,線性指令碼的缺點也暴露出來了:
元素定位
、元素操作細節
、測試資料
、結果驗證(斷言)
是捆綁在一起的,程式碼會顯得非常冗餘、可讀性差、不可複用、工作量大且可維護性差POM:Page Object Model,頁面物件模型
的簡稱
2013年,由Martin Fowler提出了PageObject的觀點
作者的觀點是一種封裝思想,旨在為每個待測頁面建立一個頁面物件,從而將繁瑣的定位元運算、操作細節封裝到這個頁面物件中,對外只提供必要的操作介面,在呼叫的時候只呼叫提供的介面,不用去呼叫操作細節,最終實現程式的高內聚低耦合,使程式模組的可重用性、移植性大大增強
在這種模式下,對於應用程式中的每個頁面都應該有相應單獨的頁面類(例如:login_page、userinfo_page),類中應該包含此頁面上的元素物件
和操作這些元素物件所需要的方法
再將流程所關聯的頁面作為物件,將物件串聯起來形成不同的業務流程,例如:在登入頁面完成登入操作後跳轉到使用者中心頁面進行個人資訊的修改
2015年,Selenium官方對PageObject進行引入:
2020年,Selenium更新檔案地址:
https://www.selenium.dev/documentation/test_practices/encouraged/page_object_models
The public methods represent the services that the page offers
用公共方法表示頁面提供的服務
例如:登入頁面,有使用者名稱輸入框、密碼輸入框、登入按鈕,於是就可以用input_username()代表輸入使用者名稱、用input_password()代表輸入密碼、用click_submit()代表點選登入按鈕
Try not to expose the internals of the page
儘量不要暴露頁面的內部資訊
將操作細節封裝成方法,對外只提供對應的方法供呼叫
Generally don’t make assertions
一般不使用斷言
斷言要和Page程式碼分開,不要將斷言寫在PageObject層
Methods return other PageObjects
方法返回其他PageObjects
例如:首頁有個方法是點選登入圖示跳轉到登入頁面,因此這個方法應該返回login_page
Need not represent an entire page
不需要表示整個頁面
不需要對頁面中的每一個元素進行建模,只需要關注我們需要用到的元素。例如:登入頁面除了賬號密碼登入,還有快捷登入、手機簡訊登入、掃碼登入等
Different results for the same action are modelled as different methods
同一行為的不同結果可以用不同的方法來模擬
例如:對一個頁面進行操作,可能出現正確的結果或者錯誤的結果,可以為這兩種不同的結果分別建立兩個不同的方法
GitHub:關注微信公眾號 IT小學生蔡坨坨,回覆關鍵字 原始碼獲取
base:base_page,基礎類別,定義專案所需的基礎方法,對Selenium一些常用的api進行二次封裝,如:find_element、click、send_keys、screenshot、呼叫JavaScript指令碼的方法以及其他與瀏覽器相關的操作
為什麼要有基礎類別?
pages:page_object,頁面物件層,也是PO的核心層,繼承BasePage,管理頁面元素以及操作元素的方法(將操作元素的動作寫成方法)
cases:測試用例層,用於管理測試用例,這裡會用到單元測試框架,如:Pytest、Unittest。
data:測試資料層,用於測試資料的管理,資料與指令碼分離,降低維護成本,提高可移植性,如:yml 檔案資料
config:組態檔層,存放整個專案需要用到的設定項,如:URL、資料庫資訊等
utils:CommonUtil,公共模組,將一些公共函數、方法以及通用操作進行封裝,如:紀錄檔模組、yaml 操作模組、時間模組等
run.py:批次執行測試用例的主程式,根據不同需求不同場景進行組裝,遵循框架的靈活性和擴充套件性
logs:紀錄檔模組,用於記錄和管理紀錄檔,針對不同情況,設定不同的紀錄檔級別,方便定位問題
reports:測試報告層,用於測試報告的生成和管理,如:基於 Allure 生成的客製化化報告