在我的團隊中,我們使用Appium和Appium Java-Client進行跨平臺UI測試。 我們的項目目前的結構是一樣的東西:Appium PageObject - 何時/何處實例化頁面?
mobile
pages
SignInPage
steps
SignInSteps
的步驟是「粘」在一起使用Cucuember。 SignInPage看起來是這樣的:
public class SignInPage {
public SignInPage(AppiumDriver driver) {
PageFactory.initElements(new AppiumFieldDecorator(driver, 15, TimeUnit.SECONDS), this);
}
// region Identifiers
final String IOS_USERNAME_FIELD = "SignInUsernameField";
final String ANDROID_USERNAME_FIELD = "new UiSelector().resourceIdMatches(\".*id/username.*\")";
final String IOS_PASSWORD_FIELD = "SignInPasswordField";
final String ANDROID_PASSWORD_FIELD = "new UiSelector().resourceIdMatches(\".*id/password_editText.*\")";
final String IOS_SIGN_IN_BUTTON = "SignInButton";
final String ANDROID_SIGN_IN_BUTTON = "new UiSelector().resourceIdMatches(\".*id/signInButton.*\")";
// endregion
@iOSFindBy(accessibility = IOS_USERNAME_FIELD)
@AndroidFindBy(uiAutomator = ANDROID_USERNAME_FIELD)
private MobileElement usernameField;
@iOSFindBy(accessibility = IOS_PASSWORD_FIELD)
@AndroidFindBy(uiAutomator = ANDROID_PASSWORD_FIELD)
private MobileElement passwordField;
@iOSFindBy(accessibility = IOS_SIGN_IN_BUTTON)
@AndroidFindBy(uiAutomator = ANDROID_SIGN_IN_BUTTON)
private MobileElement signInButton;
public MobileElement getUsernameField() {
return usernameField;
}
public MobileElement getPasswordField() {
return passwordField;
}
public MobileElement getSignInButton() {
return signInButton;
}
public void tapUsernameField() {
getUsernameField().click();
}
public void tapSignInButton() {
getSignInButton().click();
}
public void clearUsernameEditText() {
getUsernameField().clear();
}
}
我們不知道在性能和元素的查找方面是哪裏最好創建SignInPage的一個實例。目前我們的SignInSteps中有一個@Before方法,它在每個Gherkin場景開始之前執行(這不是理想的),但它有助於我們在SignInSteps類中有一個SignInPage屬性,它可以被所有步驟重用。
public class SignInSteps {
private SignInPage signInPage;
AppiumDriver driver;
@Before()
public void setUp() throws MalformedURLException {
driver = TestBase.getInstance().getDriver();
signInPage = new SignInPage(driver);
}
@Given("I fill in the username and password")
public void fill_username_and_password() throws Throwable {
signInPage.tapUsernameField();
signInPage.clearUsernameEditText();
fillEditText(signInPage.getUsernameField(), PropertiesManager.getInstance().getValueForKey(Constants.SIGN_IN_USERNAME));
fillEditText(signInPage.getPasswordField(), PropertiesManager.getInstance().getValueForKey(Constants.SIGN_IN_PASSWORD));
}
// Other sign in steps below
}
但我覺得更簡潔的方法是在SignInSteps中的每個步驟方法內創建SignInPage作爲局部變量。在創建每個步驟中需要的頁面時,是否有任何性能影響?
此外,我還不清楚,用我們目前的方法(@Before方法),爲什麼它甚至在您爲稍後將要執行的某些步驟創建頁面時仍然工作(因此屏幕甚至不可見在此刻)。
所以也許更大的問題是如何查找元素?它調用PageFactory.initElements(新的AppiumFieldDecorator(驅動程序,15,TimeUnit.SECONDS),這個);或者實際訪問註釋的屬性時(這可能是某種我從Java的知識中沒有的懶惰初始化方法,除非我對Java註釋的理解是錯誤的)。
對不起,很長的文章,但這些是我想徹底理解的一些事情。所以任何幫助,高度讚賞。
謝謝!