1. 程式人生 > >webUI自動化測試框架(三):程式碼分層-物件庫層

webUI自動化測試框架(三):程式碼分層-物件庫層

前言:做UI自動化,不可避免的要和頁面上的元素打交道,有的童鞋可能會選擇把頁面元素的定位,操作都寫在測試程式碼中,當頁面元素比較少,測試程式碼比較少的情況下還好,但是一旦頁面元素多起來(實際運用中也不太可能少),測試程式碼一多,就難以閱讀和維護了,因為元素定位的程式碼並不能直接體現我要定位的是哪個元素,當頁面元素變更了,我要去程式碼中找到該元素定位的程式碼也是比較困難的,這樣就帶了維護問題。

這裡引入我們這個框架主要的設計理念:PO模式,這個我也是學習的大牛前輩,PO模式全稱為Page Object模式,是webdriver中的一種測試設計模式,主要是將每個頁面設計為一個class,其中包含了頁面中需要測試的元素(按鈕,輸入框等),這樣在寫指令碼時,可以通過呼叫頁面類來獲取該頁面的元素。並且,當該頁面因為需求變更,帶來的元素變更時,我們也不需要改測試程式碼,只需要改這個頁面類就行了,從而使得測試程式碼與頁面元素管理分離。這樣就清晰多了,維護起來也很簡單明瞭。

但是,如果頁面多了,比如我一個後臺系統,有100多個頁面,總不能寫100個類吧,那維護起來也夠嗆,所以我們基於PO模式,再將它改良一下。

如下,進入正題:

先看分層:


1.定義一個頁面基礎類,BasePage,因為所有的頁面都有共同點,我們可以將他們抽象出來:每個頁面都有元素,每個頁面元素需要做的動作,該類主要要做的就是找到這些元素,並做出相應動作:

package com.etyero.object;

import java.util.HashMap;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

import com.etyero.utils.LogUtil;
import com.etyero.utils.UIExecutorImpl;
import com.etyero.utils.XMLUtil;

/**
 * 基礎頁面類
 * 
 * @author ljl
 */
public class BasePage extends UIExecutorImpl {
	protected WebDriver driver;
	protected String pageName;// 頁面名稱
	protected String xmlPath;// 頁面元素配置檔案路徑
	protected HashMap<String, Locator> locatorMap;//儲存頁面元素資訊
	public LogUtil log;

	public BasePage(WebDriver driver, String pageName) throws Exception {
		super(driver);
		this.driver = driver;
		this.pageName = pageName;
		// 獲取page.xml路徑,page.xml在同級目錄
		xmlPath = this.getClass().getResource("").getPath() + "page.xml";
		locatorMap = XMLUtil.readXMLDocument(xmlPath, pageName);
	}

	public void click(String locatorName) {
		super.click(getLocator(locatorName));
	}

	public void sendKey(String locatorName, String value) {
		super.sendKey(getLocator(locatorName), value);
	}

	public String getText(String locatorName) {
		return super.getText(getLocator(locatorName));
	}

	public WebElement getElement(String locatorName) {
		return super.getElement(getLocator(locatorName));
	}

	public boolean isElementDisplayed(String locatorName) {
		return super.isElementDisplayed(getLocator(locatorName));
	}

	public void switchWindow(String title) {
		super.switchWindow(title);
	}

	public void switchFrame(String locatorName) {
		super.switchFrame(getLocator(locatorName));
	}

	/**
	 * 根據locatorName返回對應的locator
	 * 
	 * @author ljl
	 */
	public Locator getLocator(String locatorName) {
		Locator locator = null;
		if (locatorMap != null) {
			locator = locatorMap.get(locatorName);
		}
		return locator;
	}
}

2.BasePage類中定義了一個變數,HashMap<String, Locator>  locatorMap,這個變數主要存放了頁面元素資訊,key為頁面元素名稱,是我們自己定義的,方便我們知道這個元素是幹嘛的,locator 儲存了這個元素的定位方式(如By.id,By.xpath),定位地址(如By.id時的id),等待時長:

package com.etyero.object;

/**
 * 封裝頁面元素,每個元素都有相應的定位地址(xpath路徑或css或id),等待時間,定位方式,預設為By.xpath
 * 
 * @author ljl
 *
 */
public class Locator {
	private String address; // 定位地址
	private int waitSec; // 等待時間
	private ByType byType; // 定位方式

	/**
	 * 定位型別列舉
	 * 
	 * @author ljl
	 *
	 */
	public enum ByType {
		by, xpath, linkText, id, name, className
	}

	public Locator() {
	}

	/**
	 * Locator構造器,預設定位型別By.xpath,等待時長3s
	 * 
	 * @author ljl
	 * @param element
	 */
	public Locator(String address) {
		this.address = address;
		this.waitSec = 3;
		this.byType = ByType.xpath;
	}

	public Locator(String address, int waitSec) {
		this.waitSec = waitSec;
		this.address = address;
		this.byType = ByType.xpath;
	}

	public Locator(String address, int waitSec, ByType byType) {
		this.waitSec = waitSec;
		this.address = address;
		this.byType = byType;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	public int getWaitSec() {
		return waitSec;
	}

	public void setWaitSec(int waitSec) {
		this.waitSec = waitSec;
	}

	public ByType getByType() {
		return byType;
	}

	public void setByType(ByType byType) {
		this.byType = byType;
	}

}

3.有了BasePage和Locator類,但是我們的頁面元素怎麼管理呢,這裡我們就要用到xml檔案了,我們將要測試的頁面定義為一個page節點,每個page節點對應一個頁面,這樣就不用寫100個類了;每個page節點下,放該頁面要測試的元素,每個元素我們給他定義好定位方式,定位地址,等待時長,以及元素名稱,元素名稱是為了方便我們知道這個元素是幹嘛的,能快速找到該元素進行維護。page.xml如下:
<?xml version="1.0" encoding="UTF-8"?>

<map>
	
	<page pageName="mainPage">
		<!--Locator lists -->
		<locator type="xpth" timeOut="30" value="/html/body/div[1]/div[7]">客服熱線</locator>
	</page>
	
	<page pageName="minePage">
		<!--Locator lists -->
		<locator type="id" timeOut="3" value="icon_user">使用者頭像</locator>
		<locator type="id" timeOut="3" value="user_name">使用者名稱</locator>						
	</page>
		
	<page pageName="loginPage">
		<!--Locator lists -->
		<locator type="id" timeOut="30" value="txtuser">登入輸入賬號框</locator>
		<locator type="id" timeOut="30" value="txtuserp">登入輸入密碼框</locator>
		<locator type="id" timeOut="30" value="btnLogin">登入</locator>
		<locator type="id" timeOut="30" value="spanMessge">錯誤提示</locator>
	</page>
</map>

舉個栗子:如上的loginPage,有賬號,密碼,登入按鈕,錯誤提示四個要測試的元素,我們給賬號元素定義了一個locator標籤,對應的定位方式為用id定位,id的值為txtuser,等待時長30s,該元素名稱我們給它取名為登入輸入賬號框,這樣,當登入框的地址變了,我們可以快速找到,這個是登入的賬號框,改掉id就行了。另外,解析xml檔案用我們第二章中基礎層的XMLUtil類方法。各司其職,清晰明瞭。

以上,對PO模式做了一個簡單的改良,不用再寫那麼多頁面類了,這也是我在大牛那學習的皮毛,相信有更好的方法,希望各位童鞋可以積極交流。

相關推薦

webUI自動化測試框架程式碼分層-物件

前言:做UI自動化,不可避免的要和頁面上的元素打交道,有的童鞋可能會選擇把頁面元素的定位,操作都寫在測試程式碼中,當頁面元素比較少,測試程式碼比較少的情況下還好,但是一旦頁面元素多起來(實際運用中也不太可能少),測試程式碼一多,就難以閱讀和維護了,因為元素定位的程式碼並不能

webUI自動化測試框架程式碼分層-操作層及用例

前面將基礎打好了,接下來就是具體的使用了,業務層主要是頁面中的各種業務操作,如登入,修改使用者資訊等,我們把這些操作都封裝在業務類中,如登入操作,我們把它封裝成一個類,登入的大致流程為開啟登入頁,輸入使用者名稱密碼,點選登入按鈕,這樣一個完整的登入業務就算完成了。 那為什麼

webUI自動化測試框架程式碼分層-基礎層

前言:該webUI自動化框架主要分為四層:基礎層、物件層、操作層、用例層,每一層負責各自的功能,這樣有益於提高程式碼的可讀性,複用性和擴充套件性。基礎層主要封裝了一些工具類,如解析xml檔案,讀取excel,分瀏覽器啟動,時間處理等,供其他類呼叫。 另外,筆者這邊主要使用的

webUI自動化測試框架簡介和Demo入門

前言:selenium和webdriver是目前主流的ui自動化測試框架之一,selenium又稱為selenium RC,基本原理為js注入,而webdriver是直接利用了瀏覽器的native support(廠商支援)來操作瀏覽器,所以,對於不同瀏覽器,必須依賴一個特

UI自動化測試框架Appium基礎

申明:本章節引用很多第三方資料和網上的教程,在參考資料tab中我都有備註,請理解。 由於該框架是基於Appium的,所以先講講appium的基礎知識 一:Appium介紹 Appium是由nodejs的express框架寫的Http Server

Pytest測試框架pytest fixture 用法

xUnit style 結構的 fixture用於初始化測試函式, pytest fixture是對傳統的 xUnit 架構的setup/teardown功能的改進。pytest fixture為測試準備一個良好的測試環境,測試函式使用的每個 fixture通常有一個引數(以 fixture 命名),測試函式

自動化服務部署Linux下安裝Git

ima yum lan 參考 lease 指令 mage sta shu Git是一個開源的分布式版本控制系統,可以有效、高速的處理從很小到非常大的項目版本管理,是目前使用範圍最廣的版本管理工具。 這篇博客,介紹下Linux下安裝Git的步驟,僅供參考,當然,還是yum安裝

性能測試入門性能測試工具

需求 pre tor 不足 廠商 ecdh 腳本編寫 ssi 3.1 這篇文章介紹下性能測試工具: 簡單模擬工具 有很多場景下,我們只是想做一個簡單的壓測,對於監測結果要求並不高,壓測的場景也比較簡單,不想安裝復雜的工具,這種情況下,推薦使用簡單的模擬工具進行就可以了。 a

初識gauge自動化測試框架

numbers 引用 文件中 自動化測試 文件描述 tor 興趣 測試 你是 看到一些同學對該工具有點一興趣,那麽我將繼續介紹Gauge自動化測試工具。 Gauge本質上一個BDD(Behavior Driven Development)測試框架。所以,首先你要了解BDD的

scrapy爬蟲框架爬取桌布儲存並命名

寫在開始之前 按照上一篇介紹過的 scrapy爬蟲的建立順序,我們開始爬取桌布的爬蟲的建立。 首先,我們先過一遍 scrapy爬蟲的建立順序: 第一步:確定要在pipelines裡進行處理的資料,寫好items檔案 第二步:建立爬蟲檔案,將所需要的資訊從

[翻譯]pytest測試框架使用

此文已由作者吳琪惠授權網易雲社群釋出。 歡迎訪問網易雲社群,瞭解更多網易技術產品運營經驗。 呼叫pytest 呼叫命令: python -m pytest [...] 上面的命令相當於在命令列直接呼叫指令碼 pytest [...](前提是python已經加入環境變數) 一些幫

pytest+allure自動化測試框架

  pytest是Python最流程的單測框架之一。 在本文中,我們將會介紹pytest的特點,功能和使用。 Demo 安裝Python依賴庫:pip3 install pytestpip3 install pytest-allure-adapto 檔案目錄: 三個pytest測試指令碼

RobotFramework自動化測試框架1- RobotFramework簡介

 對於RobotFramework自動化測試框架,我這裡會從三個單元進行闡述,希望能對你有幫助。 RobotFramework簡介 RobotFramework是什麼? Robotframework 是由python編寫的,一個開源的基於關鍵詞驅動的自動化測試框架,它可以做基於UI或者介面

RobotFramework自動化測試框架2- RobotFramework語法

RobotFramework測試用例是由四部分組成的,下面就從這四個部分簡單介紹語法: 關鍵字表 *** Keywords *** 設定表 *** Settings *** 變量表 *** Variables *** 測試用例表 *** Testcases ***  

Java類集框架Set子介面

Set子介面只是簡單地繼承了Collection介面,並沒有擴充其他的方法。Set集合中不允許儲存重複的資料。在Set介面下有兩個常用的子類:HashSet、TreeSet。HashSet是雜湊存放資料,而TreeSet是有序存放的子類,預設按照字母的升序排列。在實際開發中如果沒有排序要求,

【selenium3+JAVA】介面自動化測試教程——瀏覽器的全屏、最大化和設定大小位置

1、瀏覽器全屏 使用程式碼如下: ChromeDriver chrome = new ChromeDriver(); chrome.manage().window().fullscreen(); 如上程式碼會把瀏覽器全屏,效果嘛就是除了網站的內容部分,其他全部

談談單元測試測試工具 JUnit 4

前言 上一篇文章《測試工具 JUnit 3》簡單的討論了 JUnit 3 的使用以及內部的方法。這篇文章將會在 JUnit 3 的基礎上,討論一下 JUnit 4 的新特性。同時,與 JUnit 3 做一個簡單的對比。那麼,廢話就不多說了,直

Robot Framework自動化測試框架

最近看到同學發了一篇RobotFramework自動化測試框架的文章,感覺已經很久沒有主動或被動接觸到其他的測試框架(感覺過了一萬年),遂抽了點時間瞭解了下這個東東。自動化測試大體思路類似,因此本文僅作簡單介紹。一、動手實踐動手實踐來源於:http://www.cnblogs

集合框架HashMap原始碼解讀

一、前言  在分析jdk1.8後的HashMap原始碼時,發現網上好多分析都是基於之前的jdk,而Java8的HashMap對之前做了較大的優化,其中最重要的一個優化就是桶中的元素不再唯一按照連結串列組合,也可以使用紅黑樹進行儲存,總之,目標只有一個,那就是在安全和功能性完備

UI自動化測試經驗之談

如何把自動化用例執行是否成功的結果寫入日誌(log) 博主剛入門selenium自動化測試的時候,碰到的一個沒想明白的問題,我們知道需要通過斷言來決定這個用例是否執行成功Success or F