[英]Handling environments with similar page logic but different locators
我有一個測試套件,當前可在不同的開發環境中運行。 最近,已經完成了對應用程序的完全重寫,並將其部署到了新環境中。
該應用程序的外觀和行為幾乎相同。 頁面邏輯或多或少是相同的。 最大的不同是HTML重寫使我的定位器無用。 我不確定如何在這個新環境中處理定位器,同時又堅持頁面對象模型。
頁面對象模型聲明所有頁面邏輯應保留在相應的頁面對象類中。 我假設這也包括定位器。
遵循這種策略會使我感到a腫的頁面對象類充滿了重復的定位符。 是否有建議的最佳實踐或干凈的解決方案來解決此問題?
我能想到的可能解決方案是:
任何人都可以評論這些解決方案是否聽起來不錯嗎? 還是提供其他建議?
一定會將pageobject類之外的定位器移動到兩個不同的類中,一個用於舊定位器,一個用於新定位器。 對每個定位器使用public static final String。 您將要遇到的問題是Java批注值需要常量表達式,因此您不能使用將不同的定位符發送到FindBy的方法。 但是您可以使用三元運算符來創建常量表達式。
下面,我添加了代碼,這些代碼基於全局標志單擊來自單個WebElement的不同按鈕,但是通過FindBy批注的“ using”值上的表達式來更改定位符。 從屬性文件初始化驅動程序時,可以在啟動時設置全局標志的值。
這是您需要包含在FindBy中的內容,並且需要將定位符發送到findElement()-using = GlobalFlag.devEnv? NewLocators.newLocxpath:OldLocators.newLocxpath 。 復制粘貼到任何地方都會很痛苦。
您可以嘗試該代碼,因為該網站是公開可用的。
class CartConstant {
//Old locators
public static final String cartxpath = "//span[.='Cart']";
}
class AccountConstant {
//New locators
public static final String accxpath = "//span[.='Account']";
}
class GlobalFlag {
//Initialize this at the start
public static final boolean devEnv = true;
}
public class ChangeAnnotation {
//Change this in the code to include the choice
@FindBy(how=How.XPATH, using=GlobalFlag.devEnv ? AccountConstant.accxpath : CartConstant.cartxpath)
private WebElement butt;
@Test
public void demoSQA() throws InterruptedException {
System.setProperty("webdriver.chrome.driver", "E:/Software Testing/Selenium/Jars/chromedriver.exe");
ChromeOptions chop = new ChromeOptions();
chop.addArguments("test-type");
chop.addArguments("start-maximized");
WebDriver driver = new ChromeDriver(chop);
driver.get("http://store.demoqa.com/products-page/product-category/imacs/");
Thread.sleep(3000);
PageFactory.initElements(driver, this);
butt.click();
}
}
這就是我設法克服這一點的方法。
我為不同的環境保留了不同的元素屬性文件。
可以說環境A,B在我的項目中,我保留了兩個名為Elements_A.properties和Elements_B.properties的屬性文件。這些屬性文件包含所有頁面元素。 如果一個元素與另一個元素不同,那將不是問題,因為在基於環境運行腳本時,您可以在腳本中引用相關的屬性文件。
可以說,在首頁的A和B中,有一個帶有不同定位符的文本框。
因此,在屬性文件A中,我們可以將元素提到為HomePage_Name_TextBox = id_NameInA “ id_NameInA”是定位符值,“ HomePage_Name_TextBox”是將用於引用該特定元素的字符串。
就像在屬性文件A中一樣,我們可以提及與HomePage_Name_TextBox = id_NameInB相同的元素“ id_NameInB”是定位符值,“ HomePage_Name_TextBox”是您將用來引用該特定元素的字符串。
您會注意到,兩個元素都具有相同的名稱( HomePage_Name_TextBox ),並且定位器值也不同。
在每個頁面類中,我都聲明了一個Map,現在您有幾個選擇來決定如何初始化頁面元素。
public class HomePage {
Map<String, String> elementsMap = new HashMap<String, String>();
//Option 1
public HomePage(Map<String, String> elementMapObj) {
elementsMap = elementMapObj;
}
//Option 2
public HomePage() {
Properties prop = new Properties();
FileReader reader;
HashMap<String, String> propertyMap = new HashMap<String, String>();
try {
reader = new FileReader(new File("CommonConfig.properties"));
prop.load(reader);
for (String key : prop.stringPropertyNames())
{
String value = prop.getProperty(key);
propertyMap.put(key, value);
}
} catch (Exception e) {
//System.out.println(e.toString());
}
try {
reader = new FileReader(new File(propertyMap.get("ElementPropFilePath")));
prop.load(reader);
for (String key : prop.stringPropertyNames())
{
String value = prop.getProperty(key);
elementsMap.put(key, value);
}
} catch (Exception e) {
//System.out.println(e.toString());
}
}
}
當您要在A中運行腳本時,可以在運行之前將公共屬性文件中的“ ElementPropFilePath”更改為“ Resources / Elements_A.properties”。 如果要在B中運行腳本,可以在運行之前將公共屬性文件中的“ ElementPropFilePath”更改為“ Resources / Elements_B.properties”(這是文件在計算機中的位置)。
簡而言之,如果您維護包含每個環境的所有元素的屬性文件,並提供該屬性詳細信息並填充每個頁面類內部的elementMap,那么您將能夠使用用於該元素的公共字符串來引用該元素。兩種環境(在此示例中為HomePage_Name_TextBox)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.