WEB自動化-10-Page Object 模型

10 Page Object 模型

10.1 概述

    在針對一個WEB頁面編寫自動化測試用例時,需要引用頁面中的元素(數據)才能進行操作(動作)並顯示出頁面內容。如果編寫的測試用例是直接針對WEB頁面元素進行操作,則無法應對經常發生變化的WEB頁面,增加日後自動化代碼的維護成本。而Page Object模型就是針對WEB頁面和元素細節的封裝,並對外提供應用級別的API,從而擺脫對WEB頁面的高耦合情況。示意圖如下所示:

    針對以上示例,可以大概總結出大概做法,如下所示:

  • 以頁面爲單位,獨立建立模型
  • 隱藏實現細節
  • 本質是面向接口編程

以上示例圖片位置:https://martinfowler.com/bliki/PageObject.html

10.2 定義

    Page Object模型(簡稱爲PO模式)是一種設計模式,其核心是分層,實現松耦合,從而實現代碼複用和其易維護性。利用PO模型,爲每個網頁建立兩個類:

  • Page類

    將每個頁面封裝爲Page類,頁面元素爲Page類成員變量頁面功能爲Page類方法裏面

  • Test類

    針對Page類定義的測試類,在測試類中調用Page類中方法完成測試。其使用Page類中的方法與頁面UI元素進行交互操作。若UI發生變化,僅需要更新Page類,測試類無需要更改。

10.3 爲什麼使用Page Object模式

    WEB由各種WEB元素(文本框、複選框、多選/單選按鈕等)組成。測試代碼與這些元素進行交互,如果不能正確管理定位器,則代碼的複雜性將成倍增加。當測試代碼和定位器的重複使用,將降低代碼的可讀性,從而進一步加大測試代碼的維護成本。 隨着項目和需求的不斷變化,開發和測試代碼的複雜性會不斷增加,維護性也隨之增加。因此,需要一種方法來解決這種問題,所以我們需要使用PO來嘗試解決這一類問題。

10.4 Page Object模型優點

    主要優點如下所示:

  • 提高代碼可複用性

    不同PO類中的Pabe Object方法可以在不同的測試用例中複用,極大提高代碼的複用性。

  • 提高代碼可維護性

    因測試場景和定位器是代碼分開,使代碼更加清晰,極大提高代碼的可維護性。

  • 減少UI對用例造成的影響

    儘管UI經常發生變更,也僅需要修改少量代碼來應對更改,從而減少其帶來的影響。

10.5 Page Object示例

10.5.1 演示環境搭建

    我們以官方提供的示例爲演示,操作步驟如下所示:

npm install minimist morgan body-parser express-session express hbs --save-dev
npm start server.js
  • 4、在瀏覽器中訪問

    默認正確的用戶名和密碼,在server.js中,可以自行修改,如下所示:

10.5.2 演示代碼

    本代碼僅僅是演示在Cypress中的Page Object模式(注意與Selenium的區別),主要示例代碼如下所示:

  • 1、新建定位器文件loginPageLoctor.json,用於存儲元素定位器
{
   "loginPage":{
       "username":"input[name=\"username\"]",
       "passwd":"input[name=\"password\"]",
       "submit":"button[type=\"submit\"]",
       "loginFailedPrompt":".error"
   }
}
  • 2、新建Page類loginPage.js,用於封裝對象和定位元素
/// <reference types="cypress" />

import LoginPageLocator from "./loginPageLoctor.json"

export default class LoginPage{
    constructor(visitUrl){
       this.url=visitUrl;
    }

    get username(){
        return cy.get(LoginPageLocator.loginPage.username);
    }

    get passwd(){
        return cy.get(LoginPageLocator.loginPage.passwd);
    }

    get submit(){
        return cy.get(LoginPageLocator.loginPage.submit);
    }

    get errorPrompt(){
        return cy.get(LoginPageLocator.loginPage.loginFailedPrompt);
    }

    get successUrl(){
        return cy.url();
    }

    visit(){
       cy.visit(this.url);
    }

    login(name,pwd) {
        if ( name !="" && pwd !=""){
            this.username.type(name);
        }

        if(pwd!=""){
            this.passwd.type(pwd);
        }

        this.submit.click();
    }

}
  • 3、新建數據文件loginData.json,用於存儲登錄的數據和數據驅動
{

    "success": [
        {
            "caseTitle": "正確的用戶名和密碼,登錄成功",
            "user": "jane.lane",
            "pwd": "password123",
            "checkpoint": "/dashboard"
        }
    ],

    "failed": [
        {
            "caseTitle": "錯誤的用戶名和正確的密碼,登錄失敗",
            "user": "Surpass",
            "pwd": "password123",
            "checkpoint": "Username and/or password is incorrect"
        },
        {
            "caseTitle": "正確的用戶名和錯誤的密碼,登錄失敗",
            "user": "jane.lane",
            "pwd": "Surpass",
            "checkpoint": "Username and/or password is incorrect"
        },
        {
            "caseTitle": "錯誤的用戶名和錯誤的密碼,登錄失敗",
            "user": "Surpass",
            "pwd": "Surpass",
            "checkpoint": "Username and/or password is incorrect"
        }
    ]

}
  • 4、新建測試類testLogin.spec.js,測試用例代碼
/// <reference types="cypress" />

import LoginPage from "./loginPage"
import UserData from "./loginData.json"

describe('登錄測試', () => {
    let baseUrl = "http://localhost:7077/login";
    let login = new LoginPage(baseUrl);
    beforeEach(() => {
        login.visit(baseUrl);
    });

    UserData.success.forEach((item)=>{
       it(item.caseTitle, () => {
           login.login(item.user,item.pwd);
           login.successUrl.should("contain",item.checkpoint)
       });
    });

    UserData.failed.forEach((item)=>{
       it(item.caseTitle, () => {
        login.login(item.user,item.pwd);
        login.errorPrompt.should("contain",item.checkpoint)
       });
    });
});

    最終的運行結果如下所示:

原文地址:https://www.jianshu.com/p/f6749544d6f8

本文同步在微信訂閱號上發佈,如各位小夥伴們喜歡我的文章,也可以關注我的微信訂閱號:woaitest,或掃描下面的二維碼添加關注:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章