Appium PageObject


原文地址http://blog.csdn.net/TalorSwfit20111208/article/details/77434950

由於無法聯系上您,在此分享您的文章,希望諒解!

Appium PageObject 直接沿用了Selenium的PageObject設計模式,

PageObject主要優點如下:

一、將UI元素與邏輯分離方便后期維護

二、減少代碼冗余

三、增強代碼可讀性

 

來看個例子

沒有使用PO設計模式的代碼如下:

 

[java]  view plain  copy
 
  1. @Test  
  2. public void twoPlusTwoOperation() {  
  3.   
  4.     /* 獲取控件*/  
  5.     MobileElement buttonTwo = (MobileElement)(driver.findElement(By.id("net.ludeke.calculator:id/digit2")));  
  6.     MobileElement buttonPlus = (MobileElement)(driver.findElement(By.id("net.ludeke.calculator:id/plus")));  
  7.     MobileElement buttonEquals = (MobileElement)(driver.findElement(By.id("net.ludeke.calculator:id/equal")));  
  8.     MobileElement resultField = (MobileElement)(driver.findElement(By.xpath("//android.widget.EditText[1]")));  
  9.   
  10.     /* 計算2+2*/  
  11.     buttonTwo.click();  
  12.     buttonPlus.click();  
  13.     buttonTwo.click();  
  14.     buttonEquals.click();  
  15.   
  16.     /* 檢查在給定的時間內是否顯示要查找的控件 */  
  17.     new WebDriverWait(driver, 30).until(ExpectedConditions.textToBePresentInElement(resultField, EXPECTED_RESULT_FOUR));  
  18.   
  19. }  

使用了PO設計模式的代碼如下

 

 

[java]  view plain  copy
 
  1. @Test  
  2. public void twoPlusTwoOperation() {  
  3.   
  4.     app.calculatorScreen().addTwoAndTwo();  
  5.     assertTrue(app.calculatorScreen().isResultCorrect("4"));  
  6.   
  7. }  

我們注意到的第一個最直接的變化是測試方法的長度。使用PageObject模式編寫的測試方法幾乎總是比原始的方法短(對於較長的測試而言更短)。如果你繼續閱讀,你會注意到,這不僅是因為我們在addTwoAndTwo方法中包裝了所有的按鈕。
可讀性怎么樣?再次通過這兩種方法,問問自己在哪種情況下更容易理解發生了什么。另外,請注意我們如何在第二種方法中真的不需要注釋,因為指定與Page Object具有的交互的方法具有重要的名稱。
通過將低級操作包含在專用方法中,我們現在有了不直接引用任何WebDriver API的測試方法。在編寫第一個PageObject測試方法時,請使用缺少引用低級API的導入語句作為根據模式進行處理的指標。
這種方法給了我們另一個不容忽視的優點:通過隱藏單一實用程序方法的技術復雜性,PageObject模式使得用戶交互的流程變得明顯。對於更長,更復雜的測試,以及我們編寫測試的整個方式的轉換,這特別有用。一旦實現了應用程序屏幕的基本交互,編寫測試方法基本上只是通過調用正確名稱所指的方法來復制用例。這就是為什么你應該努力為他們選擇最好的名字。

 

PageObject控件定位

pageobject控件定位是使用注解方式來定位的,如下

# WebElement/列表 WebElement 字段可以這樣定位:

使用@FindBy注解

 

[java]  view plain  copy
 
  1. import org.openqa.selenium.support.FindBy;  
  2. import org.openqa.selenium.WebElement;  
  3. @FindBy(someStrategy)//用來定位瀏覽器或者webview UI  
  4. //也可以用來定位native 應用,當沒有定義其他定位策略時  
  5. WebElement someElement;@FindBy(someStrategy) //用來定位瀏覽器或者webview UI  
  6. //也可以用來定位native 應用,當沒有定義其他定位策略時  
  7. List<WebElement> someElements;//定位包含相同控件屬性的控件  

使用@AndroidFindBy來定位

 

 

[java]  view plain  copy
 
  1. import io.appium.java_client.android.AndroidElement;  
  2. import org.openqa.selenium.remote.RemoteWebElement;  
  3. import io.appium.java_client.pagefactory.*;  
  4.   
  5. @AndroidFindBy(someStrategy) //用Android UI Automator來定位Android UI  
  6. AndroidElement someElement;  
  7.   
  8. @AndroidFindBy(someStrategy) //用Android UI Automator來定位Android UI  
  9.   
  10. List<AndroidElement> someElements;  


多種組合查找策略

 

 

[java]  view plain  copy
 
  1. import org.openqa.selenium.remote.RemoteWebElement;  
  2. import io.appium.java_client.pagefactory.*;  
  3. import org.openqa.selenium.support.FindBy;  
  4. import org.openqa.selenium.support.FindByAll;  
  5.   
  6.   
  7. import static io.appium.java_client.pagefactory.LocatorGroupStrategy.ALL_POSSIBLE;  
  8.   
  9. @HowToUseLocators(androidAutomation = ALL_POSSIBLE, iOSAutomation = ALL_POSSIBLE)  
  10. @FindAll{@FindBy(someStrategy1), @FindBy(someStrategy2)})   
  11. @AndroidFindBy(someStrategy1) @AndroidFindBy(someStrategy2)   
  12. @iOSFindBy(someStrategy1) @iOSFindBy(someStrategy2)   
  13. RemoteWebElement someElement;  
  14.   
  15. @HowToUseLocators(androidAutomation = ALL_POSSIBLE, iOSAutomation = ALL_POSSIBLE)  
  16. @FindAll({@FindBy(someStrategy1), @FindBy(someStrategy2)})   
  17. @AndroidFindBy(someStrategy1) @AndroidFindBy(someStrategy2)  
  18. @iOSFindBy(someStrategy1) @iOSFindBy(someStrategy2)  
  19. List<RemoteWebElement> someElements;  


## 也可以用下面這種方式: 

 

 

[java]  view plain  copy
 
  1. import org.openqa.selenium.remote.RemoteWebElement;  
  2. import io.appium.java_client.pagefactory.*;  
  3. import org.openqa.selenium.support.FindBy;  
  4. import org.openqa.selenium.support.FindByAll;  
  5.   
  6. import static io.appium.java_client.pagefactory.LocatorGroupStrategy.CHAIN;  
  7. import static io.appium.java_client.pagefactory.LocatorGroupStrategy.ALL_POSSIBLE;  
  8.   
  9. @HowToUseLocators(androidAutomation = CHAIN, iOSAutomation = ALL_POSSIBLE)  
  10. @FindAll{@FindBy(someStrategy1), @FindBy(someStrategy2)})   
  11. @AndroidFindBy(someStrategy1) @AndroidFindBy(someStrategy2)   
  12. @iOSFindBy(someStrategy1) @iOSFindBy(someStrategy2)   
  13. RemoteWebElement someElement;  
  14.   
  15. @HowToUseLocators(androidAutomation = CHAIN, iOSAutomation = ALL_POSSIBLE)  
  16. @FindAll({@FindBy(someStrategy1), @FindBy(someStrategy2)})   
  17. @AndroidFindBy(someStrategy1) @AndroidFindBy(someStrategy2)  
  18. @iOSFindBy(someStrategy1) @iOSFindBy(someStrategy2)  
  19. List<RemoteWebElement> someElements;  


或者

 

 

[java]  view plain  copy
 
  1. import org.openqa.selenium.remote.RemoteWebElement;  
  2. import io.appium.java_client.pagefactory.*;  
  3. import org.openqa.selenium.support.FindBy;  
  4. import org.openqa.selenium.support.FindByAll;  
  5.   
  6. import static io.appium.java_client.pagefactory.LocatorGroupStrategy.ALL_POSSIBLE;  
  7.   
  8. @HowToUseLocators(iOSAutomation = ALL_POSSIBLE)  
  9. @FindAll{@FindBy(someStrategy1), @FindBy(someStrategy2)})   
  10. @AndroidFindBy(someStrategy1) @AndroidFindBy(someStrategy2) //this is the chain   
  11. //by default  
  12. @iOSFindBy(someStrategy1) @iOSFindBy(someStrategy2)   
  13. RemoteWebElement someElement;  
  14.   
  15. @HowToUseLocators(iOSAutomation = ALL_POSSIBLE)  
  16. @FindAll({@FindBy(someStrategy1), @FindBy(someStrategy2)})   
  17. @AndroidFindBy(someStrategy1) @AndroidFindBy(someStrategy2) //this is the chain   
  18. //by default  
  19. @iOSFindBy(someStrategy1) @iOSFindBy(someStrategy2)  
  20. List<RemoteWebElement> someElements;  

 

應用PO查找

# Appium Java client使用了AppiumFieldDecorator來融合了Selenium PageFactory 

對象字段結構如下: 

 

[java]  view plain  copy
 
  1. import io.appium.java_client.pagefactory.*;  
  2. import org.openqa.selenium.support.PageFactory;  
  3.   
  4. PageFactory.initElements(new AppiumFieldDecorator(searchContext   
  5.               /*searchContext is a WebDriver or WebElement 
  6.               instance */),   
  7.               pageObject //對象類的一個實例  
  8. );  
[java]  view plain  copy
 
  1. import io.appium.java_client.pagefactory.*;  
  2. import org.openqa.selenium.support.PageFactory;  
  3. import java.util.concurrent.TimeUnit;  
  4.   
  5. PageFactory.initElements(new AppiumFieldDecorator(searchContext,   
  6.               /*searchContext is a WebDriver or WebElement 
  7.               instance */  
  8.         15, //默認為所有查找策略的隱式等待時間  
  9.         TimeUnit.SECONDS),   
  10.             pageObject //對象類的一個實例  
  11.   
  12. );  

 

 

[java]  view plain  copy
 
  1. import io.appium.java_client.pagefactory.*;  
  2. import org.openqa.selenium.support.PageFactory;  
  3. import java.util.concurrent.TimeUnit;  
  4.   
  5. PageFactory.initElements(new AppiumFieldDecorator(searchContext,   
  6.               /*searchContext is a WebDriver or WebElement 
  7.               instance */  
  8.         new TimeOutDuration(15, //默認為所有查找策略的隱式等待時間  
  9.   
  10.         TimeUnit.SECONDS)),   
  11.             pageObject //對象類的一個實例  
  12.   
  13. );  


來看個經典計算器程序在PageObject中的實際應用

 

項目結構
安裝程序的核心組件將是以下類:

  • AbstractTest:我們在其中設置測試階段;
  • AppiumDriverBuilder:設置所需的功能並實例化驅動程序;
  • 我們調用的應用程序類訪問我們的Screen對象;
  • AbstractScreen,包含您的Screen對象之間的所有共享方法;
  • Screen類包含表示用戶與被測試應用程序交互的方法;
  • 測試類包含一個或多個測試,寫成屏幕方法調用序列。

為了進一步澄清項目結構,您可以將這些類組織成包。在一個實用程序包中,您可以包括您的AppiumDriverBuilder類以及您創建的其他實用程序類。您也可以將AbstractScreen類和其他Screen類放在屏幕包中。項目結構如下:


 

 

AbstractTest
在項目的中心是AbstractTest類。這里我們定義我們的測試套件方法,它將在每次測試運行之前執行。這里我們做兩件非常重要的事情:

  1. 負責初始化負責連接到Appium服務器的驅動程序;
  2. 實例化了App類,這將允許我們訪問我們想要測試的應用程序的單個屏幕;

 

 

[java]  view plain  copy
 
  1. package com.test.calculatortest;  
  2.   
  3. import com.test.calculatortest.Calculator;  
  4. import com.test.calculatortest.util.AppiumDriverBuilder;  
  5.   
  6. import io.appium.java_client.AppiumDriver;  
  7.   
  8. import org.junit.Before;  
  9.   
  10. import java.net.MalformedURLException;  
  11. import java.net.URL;  
  12.   
  13. public abstract class AbstractTest {  
  14.   
  15.     private AppiumDriver<?> driver;  
  16.     protected Calculator app;  
  17.   
  18.     /* Establish a connection to TestObject, or to a local device test is local. */  
  19.     @Before  
  20.     public void connect() throws MalformedURLException {  
  21.   
  22.         this.driver = AppiumDriverBuilder.forAndroid()  
  23.                 .withEndpoint(new URL("http://127.0.0.1:4723/wd/hub"))  
  24.                 .build("com.android.calculator2", ".Calculator");  
  25.         //實例化應用類  
  26.         app = new Calculator(driver);  
  27.   
  28.     }  
  29.   
  30. }  

 

AppiumDriverBuilder
它基本上是一個支持類,負責配置和實例化的Appium驅動程序。

[java]  view plain  copy
 
  1. package com.test.calculatortest.util;  
  2.   
  3. import io.appium.java_client.AppiumDriver;  
  4. import io.appium.java_client.android.AndroidDriver;  
  5. import io.appium.java_client.android.AndroidElement;  
  6.   
  7. import org.openqa.selenium.remote.DesiredCapabilities;  
  8.   
  9. import java.net.URL;  
  10.   
  11. public abstract class AppiumDriverBuilder<SELF, DRIVER extends AppiumDriver<?>> {  
  12.   
  13.   
  14.   
  15.     public static AndroidDriverBuilder forAndroid() {  
  16.         return new AndroidDriverBuilder();  
  17.     }  
  18.   
  19.     public static class AndroidDriverBuilder extends AppiumDriverBuilder<AndroidDriverBuilder, AndroidDriver<?>> {  
  20.   
  21.         DesiredCapabilities capabilities = new DesiredCapabilities();  
  22.   
  23.         @Override  
  24.         public AndroidDriver<?> build(String appPackage,String appActivity) {  
  25.   
  26.               
  27.               
  28.               
  29.             capabilities.setCapability("platformName", "Android");  
  30.             //使用Android模擬器  
  31.             capabilities.setCapability("deviceName", "testDevice");  
  32.             //使用Android模擬器  
  33.             capabilities.setCapability("platformVersion", "4.4.4");  
  34.             //不重新安裝應用  
  35.             capabilities.setCapability("noReset",true);  
  36.             //待測包名及首次啟動的頁面  
  37.             capabilities.setCapability("appPackage", appPackage);  
  38.             capabilities.setCapability("appActivity", appActivity);  
  39.             //使用appium Unicode鍵盤輸入法,輸入完畢后重置輸入法  
  40.             capabilities.setCapability("unicodeKeyboard", true);  
  41.             capabilities.setCapability("resetKeyboard", true);  
  42.               
  43.             capabilities.setCapability("deviceReadyTimeout",30);  
  44.   
  45.             return new AndroidDriver<AndroidElement>(endpoint, capabilities);  
  46.   
  47.         }  
  48.   
  49.       
  50.   
  51.     }  
  52.   
  53.     protected URL endpoint;  
  54.   
  55.     @SuppressWarnings("unchecked")  
  56.     public SELF withEndpoint(URL endpoint) {  
  57.         this.endpoint = endpoint;  
  58.   
  59.         return (SELF) this;  
  60.     }  
  61.   
  62.     public abstract DRIVER build(String appPackage,String appActivity);  
  63.   
  64. }  

應用類
測試中的另一個中心類將是Application類(我們簡單的命名為我們正在測試的應用程序的名稱)。這個類的功能是提供屏幕(正如我們之前所說的,Page對象)到需要訪問它們的功能的方法(屏幕類中的測試方法)。

[java]  view plain  copy
 
  1. package com.test.calculatortest;  
  2.   
  3.   
  4. import com.test.calculatortest.screen.CalculatorScreen;  
  5.   
  6.   
  7. import io.appium.java_client.AppiumDriver;  
  8. /* 
  9.  * 應用類,返回各個操作頁面類 
  10.  */  
  11. public class Calculator {  
  12.   
  13.   
  14.     private final AppiumDriver<?> driver;  
  15.   
  16.   
  17.     public Calculator(AppiumDriver<?> driver) {  
  18.         this.driver = driver;  
  19.     }  
  20.   
  21.   
  22.     public CalculatorScreen calculatorScreen() {  
  23.         return new CalculatorScreen(driver);  
  24.     }  
  25.   
  26.   
  27. }  

AbstractScreen類

AbstractScreen類將包含Screen對象之間共享的所有方法。這些可能是通用目的的方法,可以執行多個點(滑動,滾動)與應用程序交互所需的手勢,這些手段隱藏了一些更為復雜的代碼,從而增加了測試方法的可讀性,同步方法等。

 

[java]  view plain  copy
 
  1. package com.test.calculatortest.screen;  
  2.   
  3. import io.appium.java_client.AppiumDriver;  
  4. import io.appium.java_client.MobileElement;  
  5. import io.appium.java_client.pagefactory.AppiumFieldDecorator;  
  6. import org.openqa.selenium.By;  
  7. import org.openqa.selenium.OutputType;  
  8. import org.openqa.selenium.support.PageFactory;  
  9. import org.openqa.selenium.support.ui.ExpectedConditions;  
  10. import org.openqa.selenium.support.ui.WebDriverWait;  
  11.   
  12. public abstract class AbstractScreen {  
  13.   
  14.     protected final AppiumDriver<?> driver;  
  15.   
  16.     public AbstractScreen(AppiumDriver<?> driver) {  
  17.         this.driver = driver;  
  18.   
  19.         PageFactory.initElements(new AppiumFieldDecorator(driver), this);  
  20. }  
  21.   
  22.     public MobileElement findElementWithTimeout(By by, int timeOutInSeconds) {  
  23.         return (MobileElement)(new WebDriverWait(driver, timeOutInSeconds)).until(ExpectedConditions.presenceOfElementLocated(by));  
  24.     }  
  25.   
  26.     protected void takeScreenShot(){  
  27.         driver.getScreenshotAs(OutputType.BASE64);  
  28.     }  
  29.   
  30. }  

注意
PageFactory.initElements(new AppiumFieldDecorator(driver), this);這句,這可以讓你使用注釋來抓取UI元素,因此請勿忘記將其包含在您的設置中!

 

屏幕類
屏幕類代表應用程序的屏幕。在這里獲取UI元素並與代表可能與用戶界面交互的方法與其進行交互,例如打開菜單並選擇項目,填寫某些字段並按下提交按鈕,向下滾動列表並選擇正確的元素這樣,你的測試方法將只是不同屏幕上的一系列用戶交互。這將使你的測試易於維護和擴展。

 

[java]  view plain  copy
 
  1. package com.test.calculatortest.screen;  
  2.   
  3. import io.appium.java_client.AppiumDriver;  
  4. import io.appium.java_client.MobileElement;  
  5. import io.appium.java_client.pagefactory.AndroidFindBy;  
  6. import org.openqa.selenium.TimeoutException;  
  7. import org.openqa.selenium.support.ui.ExpectedConditions;  
  8. import org.openqa.selenium.support.ui.WebDriverWait;  
  9.   
  10. public class CalculatorScreen extends AbstractScreen {  
  11.   
  12.     @AndroidFindBy(id = "com.android.calculator2:id/digit2")  
  13.     private MobileElement buttonTwo;  
  14.   
  15.     @AndroidFindBy(id = "com.android.calculator2:id/plus")  
  16.     private MobileElement buttonPlus;  
  17.   
  18.     @AndroidFindBy(id = "com.android.calculator2:id/equal")  
  19.     private MobileElement buttonEquals;  
  20.   
  21.     @AndroidFindBy(xpath = "//android.widget.EditText[1]")  
  22.     private MobileElement resultField;  
  23.   
  24.     public CalculatorScreen(AppiumDriver<?> driver) {  
  25.         super(driver);  
  26.     }  
  27.   
  28.     public void addTwoAndTwo() {  
  29.   
  30.         buttonTwo.click();  
  31.         buttonPlus.click();  
  32.         buttonTwo.click();  
  33.         buttonEquals.click();  
  34.   
  35.     }  
  36.   
  37.     public boolean isResultCorrect(String result) {  
  38.   
  39.         try {  
  40.   
  41.             /* Check if within given time the correct result appears in the designated field. */  
  42.             (new WebDriverWait(driver, 30)).until(ExpectedConditions.textToBePresentInElement(resultField, result));  
  43.             return true;  
  44.   
  45.         } catch (TimeoutException e) {  
  46.   
  47.             return false;  
  48.   
  49.         }  
  50.   
  51.     }  
  52.   
  53. }  

除了剛剛描述的應用程序的顯着“主屏幕”之外,我們還可以創建另一個表示計算器應用程序的“高級面板”的程序,這基本上是自己的屏幕。在此屏幕中引用的UI元素將是計算器的符號/函數。
你可以為應用程序的每個屏幕創建一個Screen對象,也可以決定僅對真正重要的屏幕執行此操作。這兩種方法都有其優點和缺點,但請記住,可以使用太多屏幕的應用程序來處理,另一方面,在一個Screen對象中抽取太多的屏幕可能會導致混亂。
測試類
您的測試按照擴展AbstractTest的類進行分組。這允許您抓住應用程序的任何屏幕,並通過您編寫的方法與其進行交互。

 

 

[java]  view plain  copy
 
  1. package com.test.calculatortest;  
  2.   
  3.   
  4. import org.junit.Test;  
  5.   
  6.   
  7. import static org.junit.Assert.assertTrue;  
  8. /* 
  9.  *  
  10.  * 邏輯操作類 
  11.  * 
  12.  */  
  13. public class OperationTests extends AbstractTest {  
  14.   
  15.   
  16.     public OperationTests() {}  
  17.   
  18.   
  19.     /* 一個簡單的加法運算,期望結果為正確的值 */  
  20.     @Test  
  21.     public void twoPlusTwoOperation() {  
  22.   
  23.   
  24.         app.calculatorScreen().addTwoAndTwo();  
  25.         assertTrue(app.calculatorScreen().isResultCorrect("4"));  
  26.   
  27.   
  28.     }  
  29.   
  30.   
  31. }  

將計算器的例子放在一邊,並跳入一個現實世界的例子:

 

 

[java]  view plain  copy
 
  1. public class ChatTest extends AbstractTest {  
  2.     @Test  
  3.         public void sendMessageAndCheckHistoryTest() {  
  4.   
  5.             login(Credentials.VALID_USER_CREDENTIALS);  
  6.   
  7.              app.mainScreen().startChatWithUser(TEST_USERNAME);  
  8.   
  9.             app.chatScreen().sendChatMessage(TEST_MESSAGE);  
  10.   
  11.             app.chatScreen().navigateToHistoryScreen();  
  12.             assertTrue(app.historyScreen().containsMessage(TEST_MESSAGE));  
  13.   
  14.         }  
  15.   
  16.   
  17.         @Test  
  18.         public void sendAndDeleteMessageThenCheckHistoryTest() {  
  19.   
  20.   
  21.             ...  
  22.   
  23.   
  24.         }         
  25.   
  26.   
  27. }  

正如你所看到的,當涉及多個屏幕時,這種模式的目的變得清晰,方便起見。我們現在正在瀏覽我們從未見過的一系列屏幕,但是我們已經可以得到我們測試中發生了什么的一般概念。如果我們看看我們調用的屏幕方法的實現,我們將會更准確地了解發生了什么。事實上,我們可以在沒有這樣做的情況下收集一些信息是使用PageObject編寫測試的好處之一。
如果UI發生小的變化,我們可能不需要改動我們的測試方法:改動將在我們的屏幕方法之一發生。在這種變化頻繁的敏捷環境中,除了測試腳本的強大性外,還特別受歡迎。
您可以選擇自己的屏幕方法的復雜程度。擁有更多,更簡單的屏幕方法將導致更長,更詳細的測試方法,暴露更多的交互的復雜性。按照這種方法,上述方法看起來更像這樣:

[java]  view plain  copy
 
  1. @Test  
  2. public void sendMessageAndCheckHistoryTest() {  
  3.   
  4.     login(Credentials.VALID_USER_CREDENTIALS);  
  5.   
  6.     app.mainScreen().navigateToUserSelection();  
  7.   
  8.     app.userSelectionScreen().selectUser(TEST_USERNAME);  
  9.   
  10.     app.userProfileScreen().startChat();  
  11.   
  12.     app.chatScreen().sendChatMessage(TEST_MESSAGE);  
  13.     app.chatScreen().navigateToMainScreen();  
  14.   
  15.     app.mainScreen().navigateToHistoryScreen();  
  16.   
  17.     assertTrue(app.historyScreen().containsMessage(TEST_MESSAGE));  
  18.   
  19.   
  20.   
  21.   
  22. }  

雖然這種方法顯示了屏幕之間的每個過渡,但是它可能很容易成為壓倒性的,如在這個例子中:

 

 

[java]  view plain  copy
 
  1. public class CreateDocumentationWithSuggestionTest extends AbstractTest {  
  2.   
  3.     @Test  
  4.     public void buildNewDocumentationWithSuggestions() {  
  5.   
  6.         app.documentationScreen().navigateToSettings();  
  7.         app.settingsScreen().navigateToSuggestions();  
  8.         app.settingsScreen().activateSuggestions(SUGGESTIONS));  
  9.         app.settingsScreen().navigateToDocumentation();  
  10.         app.documentationScreen().createDocumentation();  
  11.         app.documentationCreationScreen().selectCultivation();  
  12.         app.documentationDetailsScreen().selectFields(TEST_CULTIVATION_1.getFields());  
  13.         app.documentationDetailsScreen().selectConsumables(TEST_CULTIVATION_1.getConsumables());  
  14.         app.documentationDetailsScreen().selectWorkers(TEST_CULTIVATION_1.getWorkers());  
  15.         app.documentationDetailsScreen().sendActivity();  
  16.         app.documentationScreen().createDocumentation();  
  17.         app.documentationCreationScreen().selectCultivation();  
  18.         Assert.assertTrue(app.documentationDetailsScreen().areSuggestedFieldsFilledOut(TEST_CULTIVATION_1));  
  19.   
  20.     }  
  21.     ...  
  22.   
  23. }  

您應該保持測試方法足夠短,以便您能夠一目了然地告訴他們做什么,而不用將所有內容都包裝到單一屏幕方法中。尋找平衡是編寫一個好的,可維護的測試套件的關鍵。
總結:
PageObject前期可能工作量有點多,但是后面都是照葫蘆畫瓢非常容易維護,所以使用起來性價比還是挺高的,相比直來直去的測試腳本也減少了大量的重復代碼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM