將網頁元件資訊與自動化測試邏輯分離(Page Object的應用)
這篇文章主要說明當網頁元件頻繁的修改時要如何減少程式的修改?
從網頁作 End to End 的網站自動化測試其中一個最大的困難是畫面修改時,
自動化測試程式也必須對應的修改。因此,如何將程式修改的範圍減少,
或是更有效率的管理這些畫面的修改就是這篇要討論的重點。
我們主要介紹 Page Object 的設計觀念,並且用一個實作說明。
什麼是 Page Object?
如下圖所示,左邊沒有使用 Page Object 的寫法是 Class A 的程式內容包含 WebElement 網頁元件的定位與測試邏輯
右邊為採用 Page Object 則是將程式分為兩個 Class。 Class A為 WebElement 。 Class B 為測試邏輯。
如此一來,如果畫面修改,或是其他測試程式有參考到這個畫面的 WebElement 我們只需要修改 WebElement 的 class 就可以。
簡單來說就是也就是:我們”將畫面所有的元件定位 Web Element locators 集中寫在一個地方”。
這個地方可以是 Class或是簡單的使用文字檔。
使用 class 的優點是可以把常用的元件處理行為定義。
使用文字檔的優點是可以隨時修改內容不需要重新編譯,缺點是無法像 class 那樣定義成用的函數。
實作測試情境
我們的測試程式主要完成下列項目
1. 啟動 FireFox 瀏覽器,開啟 google 網頁
2. 定義好 Google 網頁上的 Search Bar 與 Search Button於 properties 檔案中。
3. 透過測試程式讀取 properties,定位到 Search Bar 之後,輸入收尋關鍵字。
使用Properties 檔案實作
我們將利用 properties 文字檔的方式存放 Web Element locator實作。所以程式會分成三大部分:
- 1: Properties 檔案:這個主要是文字檔,定義網頁元件的位置。例如 ID, Name or Xpath 等 (WebElements.Properties)
- 2: 讀取 Properties 檔案的 Parser: 這個程式主要負責讀取 Properties 所定義的網頁定位(WebElementPropertiesParser.java)
- 3: 測試程式: 自動化測試程式。(GoogleTestByProperties.java)
1. 網頁元件定位的 Property 檔案
首先我們先定義 Property,這個檔案會定義所有我們需要的網頁元件的定位。網頁元件的定位主要由兩大部分組成,一個是
- Locator type 也就是 name, id 或是 Xpath等。
- Locator 的值。例如 Locator type 為Xpath的話,那麼這個值就是 //*[@name=’q’]
格式我們自訂如下:
## Element Name (程式讀取用的變數名)= Locator type: Locator value
SearchField = Name:q
SearchField = Xpath://*[@name=’q’]
[pastacode lang=”java” message=”” highlight=”” provider=”manual”]
## Element Name = Locator type: Locator value
## Locator needs to be one of value below
## Name, Id, CssSelector, LinkText, PartialLinkText, Xpath, TagName
## Google Home page Web Elements Htts://www.google.com/
SearchField = Xpath://*[@name="q"]
SearchButton= Name:btnk
[/pastacode]
2. 讀取Properties 的 parser
這個程式主要用來讀取 properties所定義的網頁元件位置。
[pastacode lang=”java” message=”” highlight=”” provider=”manual”]
package mySelenium;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
import org.openqa.selenium.By;
public class WebElementPropertiesParser {
private FileInputStream stream;
private String RepositoryFile;
private Properties propertyFile = new Properties();
public WebElementPropertiesParser(String fileName) throws IOException
{
this.RepositoryFile = fileName;
stream = new FileInputStream(RepositoryFile);
propertyFile.load(stream);
}
public By getbjectLocator(String locatorName)
{
String locatorProperty = propertyFile.getProperty(locatorName);
System.out.println(locatorProperty.toString());
String locatorType = locatorProperty.split(":")[0];
String locatorValue = locatorProperty.split(":")[1];
By locator = null;
switch(locatorType)
{
case "Id":
locator = By.id(locatorValue);
break;
case "Name":
locator = By.name(locatorValue);
break;
case "CssSelector":
locator = By.cssSelector(locatorValue);
break;
case "LinkText":
locator = By.linkText(locatorValue);
break;
case "PartialLinkText":
locator = By.partialLinkText(locatorValue);
break;
case "TagName":
locator = By.tagName(locatorValue);
break;
case "Xpath":
locator = By.xpath(locatorValue);
break;
}
return locator;
}
}
[/pastacode]
3. 測試程式
這個測試程式主要就是透過步驟2的parser 讀取properties 檔案中的 SearchField的值。Xpath://*[@name=”q”]
WebElement SearchField = driver.findElement(parser.getbjectLocator(“SearchField”));
[pastacode lang=”java” message=”” highlight=”” provider=”manual”]
package mySelenium;
import java.io.IOException;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import mySelenium.WebElementPropertiesParser;;
public class GoogleTestByProperties {
private WebElementPropertiesParser parser;
private WebDriver driver;
@BeforeClass
public void setUp() throws IOException
{
driver = new FirefoxDriver();
driver.get("http://www.google.com/");
parser = new WebElementPropertiesParser("D:\\mySeleniumJava\\src\\mySelenium\\WebElements.properties");
}
@Test
public void testGoogleSearch()
{
WebElement SearchField = driver.findElement(parser.getbjectLocator("SearchField"));
SearchField.sendKeys("Java Properties testing");
}
@AfterClass
public void tearDown() throws InterruptedException
{
Thread.sleep(5000);
driver.quit();
}
}
[/pastacode]
如此一來,未來就算網頁元件定位有修改,我們只需要修改properties文字檔即可。