在过去的一年里,我为我的团队构建了一个非常好的WebDriver框架。相当标准:在我们的平台上,页面类通常封装了页面的全部功能(通过对象控制,根据需要使用方法),并使用一些全局方法扩展基类,在JUnit测试类中调用多个页面,典型的断言方法,yada yada。没有什么华而不实的东西--非常循规蹈矩,但非常实用和灵活。
然而,最近,我被要求使用这个框架来自动化大量具有表单的页面,这些表单可以容纳100个甚至更多的输入、选择、选项等。这让我感到非常震惊。此外,许多自定义表单控件的id随着环境的不同而变化(幸运的是,在最初的推送之后,它们在每个环境中保持不变)。不管怎样..。
让我们来看看我每天使用的一个典型的PageObject结构:
/** Constructor*/
public someConstructor(WebDriver driver){
super(driver, pageTitle);
}
/**Locators*/
By searchBoxLocator = By.id("phSearchInput");
By searchBoxClearLocator = By.id("phSearchClearButton");
By searchButtonLocator = By.cssSelector("input[value='Search']");
/**Some Methods*/
public void selectFromTabBar(String tabName){
driver.findElement(By.linkText(tabName)).click();
}
public static void enterInputValue(WebDriver driver, By by, String val){
List<WebElement> elements = null;
elements = driver.findElements(by);
if(!elements.isEmpty()){
driver.findElement(by)).sendKeys(val);
}else{
throw new NoSuchElementException("Message");
}
}就像我提到的,这里没有什么异国情调,但现在我要问大家一个问题。举个例子,我不会在每个PageObject上使用传统的5-15by‘s,但是10个页面可能需要超过100个。更复杂的是,它们还将在每个环境中具有独特的值,这完全不是每个人都能掌握的,并且无法协调。因此,什么是适当的方法,我咬子弹和硬代码100“的每页,我是外部化所有的,比方说,Excel文档,并拉入所有的东西通过,我duno,JXL或任何东西,还是我硬编码的,我知道将是静态的,并把所有的东西都放在一个外部文件中吗? here...Do‘s。
归根结底,我知道没有正确的答案,但我只是好奇其他人对此的看法。现在,我已经外部化了页面的By,这些页面有如此多的表单元素,并定义了在PageObject中不会改变的控件,但感觉很笨拙。也许我太追求优雅了,但任何想法都会很奇妙。
发布于 2014-01-20 11:48:08
这主要是基于观点的,但很有趣的问题。
我的建议是模块化你的页面。
例如,你有一个有100个定位器的页面,但它们肯定不能是100个类似的文本框来让用户填写。(如果是这样,这里的解决方案可能是首先重新设计你的UI )
如果这100个元素属于不同的组件,比如顶部工具栏中的20个元素,列表视图中的20个元素,表单中的20个元素和底部工具栏中的20个元素。然后,您可能希望为每个组件创建不同的类。
例如,下面是一个普通的页面对象。
public class FooPage {
private IWebDriver driver;
public FooPage(IWebDriver driver) {
this.driver = driver;
}
public IWebElement Element1 {
get { return driver.FindElement(By.CssSelector(".something1")); }
}
// ...
public IWebElement Element100 {
get { return driver.FindElement(By.CssSelector(".something100")); }
}
public void AddItem(){
}
public void ClearList(){
}
}您可以将这些元素分成不同的组件,例如,FooPageTopToolbar、FooPageList等。
public class FooPageTopToolbar {
private IWebDriver driver;
public FooPageTopToolbar(IWebDriver driver) {
this.driver = driver;
}
// ...
public IWebElement ToolbarElement10 {
get { return driver.FindElement(By.CssSelector(".something100")); }
}
public void AddItem(){
}
}
public class FooPageList {
private IWebDriver driver;
public FooPageList(IWebDriver driver) {
this.driver = driver;
}
// ...
public IWebElement ListElement10 {
get { return driver.FindElement(By.CssSelector(".something100")); }
}
public void ClearList(){
}
}现在,您的FooPage将如下所示
public class FooPage {
private IWebDriver driver;
public FooPage(IWebDriver driver) {
this.driver = driver;
}
public FooPageTopToolbar {
get { return new FooPageTopToolbar(driver); }
}
// other components as well
public FooPageList {
get { return new FooPageList(driver); }
}
}注意这只是一个演示,你也可以考虑使用get inheritance,interfaces和abstraction来构建你的页面对象。例如,如果TopToolbar被许多其他页面共享,那么您只需要为所有页面提供一个类。如果不同的页面具有相似但略有不同的工具栏,则创建某种抽象工具栏类。
另外,你提到你对不同的环境有不同的定位器,在我看来最好的解决方案是在你的源代码中添加元素标识符(所谓的“标识符”,我指的是任何可识别的部分,可能是超文本标记语言id,但最常见的是用于测试的唯一class )。在这种情况下,您只需要一组UI开发人员不经常更改的测试定位器。
https://stackoverflow.com/questions/21225462
复制相似问题