閱讀139 返回首頁    go 阿裏雲 go 技術社區[雲棲]


Selenium的PageFactory & PageObject 在大型項目中的應用

出路出路,走出去了,總是會有路的;困難苦難,困在家裏就是難。


    因為最近遇到的技術問題一直沒找到可行的解決辦法,一直在翻看selenium的源代碼,之前寫測試代碼的時候就是拿來即用,寫什麼功能啊,就按手動的操作步驟去轉換,近日看到一個文章,又去wiki上查了查,覺得寫的不錯就記錄下來了。

    在使用selenium做UI測試的時候,往往並不是頁麵的每個功能我們都要測試,總有一些經常要進行回歸的功能,再細致一點的說,有一些節點是我們經常操作的,那麼我從項目初期開始就進行自動化測試代碼編寫的話,我們可以設計適應項目的一套自動化測試代碼結構,基本的思路就是對每一個頁麵都創建一個相應的PageObject類,如果是公共的模板頁麵當然隻建立一個就可以了。這樣下來就相當於建立了很多基礎頁麵一樣,如果項目開發的過程中還有完整的文檔或者足夠詳細的用戶故事,那麼就簡直太完美了~~因為這樣你可以減少很多次的IDE----Browser之間的切換、查找、測試工作,真的方便很多。但是這個看項目而定吧,這種細致入微的文檔很多團隊似乎都沒能做到。但是筆者還是真的希望在產品初期或項目開始的時候有完整的文檔給我們這些自動化測試的人員手中,這樣可以大大加快我們自動化測試代碼的編寫。繞的有點遠了。。。回歸正題,如何做這種一個頁麵一個基礎類的實現呢?最實際的,看代碼:

public class PageObject {

	private WebElement searchTypeSng;
	private WebElement fromCity;
	private WebElement toCity;
	private WebElement fromDate;

	public String calDate(int nextDays) {
		// 當前日期加 n 天之後 
		Date date = DateUtils.addDays(new Date(), nextDays);
		// 格式化時間格式
		return DateFormatUtils.ISO_DATE_FORMAT.format(date);
	}

	public void searchTrip(WebDriver driver,String from, String to ,String date) {
		BaseUtils.clearAndTypeString(driver,fromCity, from);
		BaseUtils.clearAndTypeString(driver,toCity, to);
		BaseUtils.clearAndTypeString(driver,fromDate, date);
		searchTypeSng.submit();
	}

}

測試執行:

public class UsingPageObject {

	public static void main(String[] args) {

		WebDriver driver = new FirefoxDriver();

		EventFiringWebDriver eventDriver = new EventFiringWebDriver(driver);
		
		eventDriver.register(new MyWebDriverListener());
		
		eventDriver.get("https://flight.qunar.com/");
		
		PageObject object = PageFactory.initElements(driver, PageObject.class);
		
		String date = object.calDate(30);
		
		object.searchTrip(driver,"北京", "廈門", date);
		

	}
}
這個時候就完成對搜索這一功能的冒煙測試,測試執行代碼沒有使用TestNG,隻是直接用了一個main函數。為了寫博客簡單方便,不推薦大家效仿。

如果還需要測試其它功能和使用其它節點,直接在PageObject類中加入相應的Field即可。

分割線-------------------------------------------------------------------------------------------------分割線

寫到這裏,如果沒用過這個方法的人會越看越暈,現在簡單的講解一下它執行的原理:

在PageObject類中我們創建的Field的名稱是和頁麵有一定的對應關係的,不是隨意取的,如果像上麵代碼這麼寫,默認的selenium會根據Id最先進行元素查找,如果沒有查找到再通過name進行查找,下麵的我就不說了,因為你已經想到了。。。如果你擔心頁麵的不規範或者複雜度比較高,容易產生ID,name,Css等的衝突,selenium不能準確的識別元素, 那麼請往下看:

selenium還提供了一種注解的方式,還是直接上代碼:

public class PageObject {
	private WebElement searchTypeSng;
	@FindBy(name="fromCity")
	private WebElement fromCity;
	@FindBy(name="toCity")
	private WebElement toWhere;
	private WebElement fromDate;

	public String calDate(int nextDays) {
		// 當前日期加 n 天之後 n=30
		Date date = DateUtils.addDays(new Date(), nextDays);
		// 格式化時間格式
		return DateFormatUtils.ISO_DATE_FORMAT.format(date);
	}

	public void searchTrip(WebDriver driver,String from, String to ,String date) {
		BaseUtils.clearAndTypeString(driver,fromCity, from);
		BaseUtils.clearAndTypeString(driver,toWhere, to);
		BaseUtils.clearAndTypeString(driver,fromDate, date);
		searchTypeSng.submit();
	}

}

當你看到這兩個annotations的時候,你已經明白了,是的,selenium提供注解的方式對頁麵的元素進行準確的定位,可以參考的關鍵字有:className、css、id、linkText、name、partialLinkText、tagName、xpath.

另外selenium還提供了2個關鍵字,一個是how,另一個是using,如何使用它們就不在這裏寫了,因為筆者覺得,用這兩個關鍵字更麻煩,理解起來也麻煩。

關於PageObject & PageFactory的使用,就簡單的寫了這麼多,關於PageFactory還有很多知識,我會抽出時間寫在下篇文章裏,如果有正在使用這種模式的朋友,請多多批評和指點,相互討論學習。


最後更新:2017-04-03 08:26:12

  上一篇:go JS數組操作
  下一篇:go 敏捷開發學習分享