[翻譯]-馬丁·福勒-page物件

黃博文發表於2013-09-17

譯者注:這篇文章翻譯自馬丁·福勒(Martin Flower,對,沒錯,就是軟體教父)官網的一篇文章,原文出處在文底。如果你正在做WEB自動化測試,那麼我強烈推薦你看這篇文章。另外透露Martin Flower將於10月份左右來成都ThoughtWorks辦公室,大家有機會一睹他的風采。

當你在為web頁面編寫測試時,你需要操作該web頁面上的元素來點選連結或確定顯示的內容。然後,如果你在測試程式碼中直接操作html元素,那麼你的程式碼是機器脆弱的,因為UI會經常變動。一個page物件可以封裝一個html頁面或部分頁面,通過提供的應用程式特定的API,你可以操作頁面元素而不需要在HTML中四處搜尋。

[翻譯]-馬丁·福勒-page物件

page物件的一個基本的經驗法則是page物件應該允許軟體客戶端能夠做任何人類能做的事。它也應當提供一個易於程式設計的介面,並隱藏視窗中低層的部件。所以訪問一個文字框,可以通過一個訪問方法獲取一個字串,核取方塊應當使用布林值,按鈕應當被表示為行為導向的方法名。page物件應當封裝所有的在gui控制元件本身上查詢和運算元據的方法。一個好的經驗法則是即使改變具體的控制,這種情況下page物件介面不應當發生變化。

儘管該術語是”頁面“物件,並不意味著給每個頁面都要建立一個這樣的物件,但頁面有重要意義的元素除外[1]。所以一個顯示多個相簿的頁面可以有一個相簿列表的page物件,裡面包含了幾個相簿page物件。也有可能會有一個頁首page物件及一個頁尾page物件。經驗法則是給通過給頁面建模,從而對應用程式的使用者變得有意義。

同樣,如果你導航到另一個頁面,初始page物件應當返回另一個page物件作為新頁面[2]。一般page物件的操作應當返回 基本型別(字串,日期)或另一個page物件。

有一個意見分歧的地方是page物件是由應當包含自身的斷言,或者僅僅提供資料給測試指令碼來設定斷言。在page物件中包含斷言的倡導者認為這有助於避免在測試指令碼中出現重複的斷言,可以更容易的提供更好的錯誤資訊,並且提供更接近TellDontAsk風格的API。不在page物件中包含斷言的倡導者則認為包含斷言會混合使用斷言邏輯訪問頁面資料的職責,並且導致page物件過於臃腫。

我贊成在page物件中不包含斷言。我認為你可以通過為常用的斷言提供斷言庫的方式來消除重複。這可可以提供更好的診斷。[3]

page物件通常用於測試中,但自身不應包含斷言。它們的職責是提供對基本頁面狀態的訪問。而與測試客戶端實現斷言邏輯。

我所描述的這個模式針對HTML,但同樣的模式也同樣適用於任何UI技術。我見過這種模式有效的隱藏了Java swing UI的細節,並且我深信它已經被廣泛的應用於幾乎所有其他的UI框架。

並行問題是另一個page物件可以封轉的話題。這可能涉及非同步操作中隱藏不作為非同步呈現給使用者的非同步性。也有可能涉及封裝UI框架中你不得不擔心的UI和工作執行緒之間分配行為的執行緒問題。

page物件在測試中的使用非常常見,但是也被用於在應用程式上層提供一個指令碼介面。最好將指令碼介面置於UI下層,這樣指令碼通常不復雜並且執行速度快。然而應用程式在UI層有太多的行為,那麼使用page物件可能在槽糕的工作中最好的選擇。(但是儘量將邏輯移入page object,長期來看會導致更好的指令碼即更健康的UI。)

使用一些領域特定語言來書寫測試非常普遍,比如Cucumber或一門內部DSL。如果你儘量在page物件層級之上編寫測試DSL,那麼你可以通過一個解析器將DSL宣告轉換為呼叫page物件。

如果你在測試方法中使用了WebDriver API,那麼你做錯了 – Simon Stewart.

模式有助於將邏輯從頁面元素中剝離(例如 Presentation Model, Supervising Controller, 及Passive View),從而少通過UI做測試,並且減少對page物件的需要。

page物件是封轉的一個典型示例。它們從其它元件(如測試)部件中隱藏了UI結構的細節。。如果你自問“我如何能從軟體測試中隱藏細節?”,當你做開發時在這樣的情況採用page物件不失於一個好的設計原則。封轉體現了兩方面的好處。我已經強調,通過將操作UI的邏輯限制到單個地方有助於你修改邏輯而不影響系統的其他元件。一個間接的好處是使測試端程式碼更容易理解,因為邏輯是關於測試的意圖,而會被UI細節搞亂。

進一步閱讀

I first described this pattern under the name Window Driver. However since then the term “page object” was popularized by the Selenium web testing framework and that’s become the generally used name.

我剛開始將這種模式命名為視窗驅動(Window Driver)。然而自從Selenium web測試框架使用“page object”這個名稱,page物件變成了常用的名稱。

Selenium的維基強烈推薦使用page物件,並提供瞭如果使用的建議。它也贊成page物件不包含斷言。

致謝

Perryn Fowler, Pete Hodgson及Simon Stewart為這篇部落格的草稿提供了及其有用的意見。同樣像往常一樣我非常感激ThoughtWorks軟體開發列表中的各種各樣的居民提供的建議和修正。

腳註

  1. 有觀點認為”page物件“名稱是一個誤導。因為它讓你認為一個頁面只能有一個page物件。類似皮膚物件可能會更好,但是page物件已經被廣泛接受。為什麼命名的另一個例證是TwoHardThings中的其中之一。

  2. page物件負責建立其他的page物件(比如導航)是共同的意見。然而,一些從業者更喜歡page物件返回一些通用的瀏覽器上下文,通過建立在上下文上層的page物件的測試控制是基於測試的流程(特別是條件流). 他們偏好基於測試指令碼知道那個頁面是期待的下個頁面這一事實,並且該知識不需要在page物件之間重複。特別是使用靜態型別語言通常以型別標記的方式顯示頁面導航,這樣會增加他們的喜好。

  3. page物件中包含斷言也行,儘管大多數人(比如我)更青睞無斷言風格。這些斷言可以檢查頁面或應用程式在此時此刻的不變數,而不是測試探索的具體東西。

本文出處: http://martinfowler.com/bliki/PageObject.html

相關文章