Appium PageObject 直接沿用了Selenium的PageObject设计模式,
PageObject主要优点如下:
一、将UI元素与逻辑分离方便后期维护
二、减少代码冗余
三、增强代码可读性
来看个例子
没有使用PO设计模式的代码如下:
@Test
public void twoPlusTwoOperation() {
/* 获取控件*/
MobileElement buttonTwo = (MobileElement)(driver.findElement(By.id("net.ludeke.calculator:id/digit2")));
MobileElement buttonPlus = (MobileElement)(driver.findElement(By.id("net.ludeke.calculator:id/plus")));
MobileElement buttonEquals = (MobileElement)(driver.findElement(By.id("net.ludeke.calculator:id/equal")));
MobileElement resultField = (MobileElement)(driver.findElement(By.xpath("//android.widget.EditText[1]")));
/* 计算2+2*/
buttonTwo.click();
buttonPlus.click();
buttonTwo.click();
buttonEquals.click();
/* 检查在给定的时间内是否显示要查找的控件 */
new WebDriverWait(driver, 30).until(ExpectedConditions.textToBePresentInElement(resultField, EXPECTED_RESULT_FOUR));
}
使用了PO设计模式的代码如下
@Test
public void twoPlusTwoOperation() {
app.calculatorScreen().addTwoAndTwo();
assertTrue(app.calculatorScreen().isResultCorrect("4"));
}
我们注意到的第一个最直接的变化是测试方法的长度。使用PageObject模式编写的测试方法几乎总是比原始的方法短(对于较长的测试而言更短)。如果你继续阅读,你会注意到,这不仅是因为我们在addTwoAndTwo方法中包装了所有的按钮。
可读性怎么样?再次通过这两种方法,问问自己在哪种情况下更容易理解发生了什么。另外,请注意我们如何在第二种方法中真的不需要注释,因为指定与Page Object具有的交互的方法具有重要的名称。
通过将低级操作包含在专用方法中,我们现在有了不直接引用任何WebDriver API的测试方法。在编写第一个PageObject测试方法时,请使用缺少引用低级API的导入语句作为根据模式进行处理的指标。
这种方法给了我们另一个不容忽视的优点:通过隐藏单一实用程序方法的技术复杂性,PageObject模式使得用户交互的流程变得明显。对于更长,更复杂的测试,以及我们编写测试的整个方式的转换,这特别有用。一旦实现了应用程序屏幕的基本交互,编写测试方法基本上只是通过调用正确名称所指的方法来复制用例。这就是为什么你应该努力为他们选择最好的名字。
PageObject控件定位
pageobject控件定位是使用注解方式来定位的,如下
# WebElement/列表 WebElement 字段可以这样定位:
使用@FindBy注解
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.WebElement;
@FindBy(someStrategy)//用来定位浏览器或者webview UI
//也可以用来定位native 应用,当没有定义其他定位策略时
WebElement someElement;@FindBy(someStrategy) //用来定位浏览器或者webview UI
//也可以用来定位native 应用,当没有定义其他定位策略时
List<WebElement> someElements;//定位包含相同控件属性的控件
使用@AndroidFindBy来定位
import io.appium.java_client.android.AndroidElement;
import org.openqa.selenium.remote.RemoteWebElement;
import io.appium.java_client.pagefactory.*;
@AndroidFindBy(someStrategy) //用Android UI Automator来定位Android UI
AndroidElement someElement;
@AndroidFindBy(someStrategy) //用Android UI Automator来定位Android UI
List<AndroidElement> someElements;
多种组合查找策略
import org.openqa.selenium.remote.RemoteWebElement;
import io.appium.java_client.pagefactory.*;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindByAll;
import static io.appium.java_client.pagefactory.LocatorGroupStrategy.ALL_POSSIBLE;
@HowToUseLocators(androidAutomation = ALL_POSSIBLE, iOSAutomation = ALL_POSSIBLE)
@FindAll{@FindBy(someStrategy1), @FindBy(someStrategy2)})
@AndroidFindBy(someStrategy1) @AndroidFindBy(someStrategy2)
@iOSFindBy(someStrategy1) @iOSFindBy(someStrategy2)
RemoteWebElement someElement;
@HowToUseLocators(androidAutomation = ALL