GUI自動化測試進階:頁面對象模式

本文介紹的是頁面對象設計模式及其常見的濫用繼承的錯誤。

本文和語言無關,但作者主要使用python和java。本文假設讀者已經具有了一定的python或java基礎,知道類和方法是什麼。

如果完全沒有這方面的基礎,請看我的《測試人員如何學Python》。

頁面對象模式主要用於基於圖形界面的自動化測試,如果沒有這方面的基礎,請看我的《Selenium的學習》。當然,本文也適用於移動端的圖形界面自動化。

一、頁面對象模式簡介

在使用頁面對象模式之前的腳本,可能是這樣的:

這樣的腳本的問題就是,我如果創建了100個腳本,每個腳本里都有用戶登錄。

當有一天用戶登錄的頁面改了:以前id叫username的文本框改成了id叫user。

我就不得不更新這全部的100個腳本。而網站往往隔三差五就要改版。這一百個腳本的維護工作很快就會把測試人員壓垮。

於是,我們引入了頁面對象,

所謂頁面對象,即是頁面元素加頁面服務:

在引入頁面對象之後,代碼的組織是這樣的:

具體到頁面類內部,是這樣的:

於是你看到的頁面類這樣的,此處我使用偽代碼來描述,請自行轉化成自己使用的語言。這裡我是假設有一個在線電影網站(我的第一個自動化框架就是針對一個在線電影網站),提供用戶註冊功能。

而腳本則是這樣的

這裡腳本的腳本本身只有一行代碼:

從註冊頁開始,先註冊新用戶,然後返回首頁,然後搜索一部電影「雷神」,最後購買。注意,這僅僅是一個例子,我以方法鏈的形式來寫了這個腳本,而且沒有加斷言。實際工作中,不建議你以方法鏈的方式來寫腳本,實際上的腳本可能是寫成這樣的:

看完這個解釋,大家是否對頁面對象有了一定的理解了呢?

那麼請嘗試一下,找一個網站,給他的某個頁面建立一個XXXPage類,然後封裝一些這個頁面的元素和服務吧。

二、面向對象不僅僅是繼承

提到面向對象,大家可能在腦海里馬上聯想到了父類和子類,多態,介面等等。這部分是面向對象的主要內容,但並非全部內容。我在日常工作中,常常見到一些編碼人員(測試或開發)寫的代碼是這樣的,一個類套一個類,一個繼承一個,十七八個類這麼繼承下來,使後續的維護者一頭霧水。有時候維護者想要修改一些東西,不知道該改哪個類。這就說明原作者的設計過頭了。所謂的「設計過度」的歷史遺留代碼,是我在工作中遇到的一個很常見的實際問題。

繼承可能是這樣的:

這樣由上往下,從父類到子類。子類具有父類的屬性和方法,並且有自己獨有的新的屬性和方法。

假設現在有一個在線電影網站要做自動化(這個網站大多數頁面都帶頭部導航欄,導航欄里包括了「電影」,「電視劇」,「綜藝」等菜單鏈接。),該自動化腳本的作者想要用頁面對象模式封裝這些頁面。由於這位測試人員學過繼承,於是他在測試框架里寫了這樣的類:

這是最典型的錯誤:濫用繼承。

錯誤的點在於帶導航欄的頁面和不帶導航欄的頁面,不應該劃分為兩個類。

設想以下場景:

如果有一天需求變了。該網站支持了一批從第三方接入的用戶(這也是一個我遇到過的實際需求噢)。對於這批新用戶,要新增一種新版的頭部導航欄,有些鏈接到原有內容,有些鏈接到這批用戶獨享的內容。網站改版成新舊導航欄並存。對老用戶只開放老版導航欄,對第三方接入的新用戶只開放新版導航欄。而頁面本體沒有其他任何變化。那麼按照這種設計就會變成這樣:

然後問題就來了:

頁面1、2、3和7、8、9除了導航欄不一樣以外,內容是完全一樣的。

而只有頁面10是專屬於新的用戶類型才能訪問的頁面。

此時,頁面123和789里完全一樣的內容寫了兩遍。那麼日常維護量就變成了兩倍。為了解決這種問題,需要引入組合模式。

三、加入組合模式

所謂組合模式,是這樣的:

引入了組合模式後,頁面對象模式是這樣的:

於是,在剛才的RegisterPage類里加入了導航欄的實例之後,這個頁面的代碼就是類似於這樣的:

僅僅只增加了一行代碼,但是這個頁面就得到了導航欄類的所有功能。假設導航欄里提供了goto_xxx_page()這樣的方法,那麼在調用時,只要

register_page.nav.goto_xxx_page()

這樣就能在registerpage類里調用到導航欄類里的方法。

這樣,就通過組合的方式,實現了頁面之間功能更好的抽象。回頭看那個導航欄發生變化的需求,一開始如果用了組合模式,那這個就不需要重複定義頁面789了。

最後我們記住設計的原則:

把頁面里可重用的模塊,看作一個又一個的小頁面。在頁面類里通過組合的方式,把這些小頁面組合進來。而不是搞一個複雜的繼承樹,一層套一層。


這是進階系列的第一篇文章,那麼,你看懂了嗎?

另,附一個我早期用java寫的頁面對象的框架例子:github.com/zhangting85/

最後,喜歡的話幫忙點個贊啦。

首發於公眾號:測試進階(test_up)

推薦閱讀:

某測試模擬器性能優化-用vprof對Python程序性能調優
HiCircle的第一款產品TestBus beta版出來啦
使用 iMacros 來自動化日常的工作
手工測試如何轉向自動化測試
自動化測試體系應該是什麼情形的?

TAG:Selenium | 自动化测试 |