天天看點

java版app自動化測試初始化模闆

項目目錄介紹
  • 目錄結構如下:

    (包含:驅動的基礎配置、全局異常處理、異常截圖、報告自動生成、app常用操作方法封裝、常用工具類封裝)

    java版app自動化測試初始化模闆
  • 各包分層關系

    basepage包負責存放app公共操作方法、AndroidDriver基礎配置、testNG公共執行順序BaseTest,對外暴露驅動等。

  • BaseApp類包含app操作有:封裝By類型的點選操作和輸入框輸入資料操作、切換到下一個視窗操作、上下左右滑動操作、具體坐标點選操作、直接使用adb指令的操作、前進後退重新整理的操作等,其它方法可自行封住。
  • 部分封裝方法如下:
/**
     * 通過元素定位拿到 Element 元素對象
     *
     * @param locator By 類型元素定位
     * @return 定位到的元素
     */
    public WebElement locateElement(AndroidDriver driver,By locator) {
        try {
            wait = new WebDriverWait(driver, 10);
            return wait.until(ExpectedConditions.presenceOfElementLocated(locator));
        }catch (NoSuchElementException | TimeoutException e) {
            System.out.println("================目前頁面未捕獲該元素,繼續執行用例==================");
        }
        return null;
    }
    /**
     * 點選元素
     * @param locator By 類型元素定位,做彈框或元素異常後接着往下執行
     * @return 點選的元素
     */
    public WebElement clickButton(AndroidDriver driver,By locator) {
        try {
            long time1 = DateUtils.getCurrentMillisecond();
            MobileElement buttonElement = (MobileElement) locateElement(driver,locator);
            wait.until(ExpectedConditions.elementToBeClickable(locator));
            if (buttonElement.isEnabled()){
                buttonElement.click();
                log.info("該點選事件耗時時間(ms):"+(DateUtils.getCurrentMillisecond()-time1));
                return buttonElement;
            }
        } catch (NoSuchElementException | TimeoutException e) {
            System.out.println("================目前頁面未捕獲該元素,截圖保留>>>>繼續執行用例==================");
            ScreenshotUtil.snapshot(driver);
        }
        return null;
//       System.out.println("改點選事件耗時時間(ms):"+(DateUtils.getCurrentMillisecond()-time1));
    }
    /**
     * 輸入框輸入資料
     * @param locator By 類型元素定位
     * @param content 輸入的内容,支援多内容,可以鍵盤輸入
     * @return 輸入框元素
     */
    public WebElement sendInput(AndroidDriver driver,By locator, CharSequence... content) {
        WebElement inputElement = locateElement(driver,locator);
        inputElement.clear();
        inputElement.sendKeys(content);
        return inputElement;
    }
 /*=====================通過動作滑動==================================*/
    /**
     *向上滑動操作
     */
    public void swipeToUp(AndroidDriver driver) {
        int width = driver.manage().window().getSize().width;
        int height = driver.manage().window().getSize().height;
        TouchAction action=new TouchAction(driver).press(PointOption.point(width/2, height*3/4)).waitAction(WaitOptions.waitOptions(duration))
                .moveTo(PointOption.point(width/2, height/4)).release();
        action.perform();
    }
    /**
     *向下滑動操作
     */
    public void swipeToDown(AndroidDriver driver) {
        int height = driver.manage().window().getSize().height;
        int width = driver.manage().window().getSize().width;
        TouchAction action=new TouchAction(driver).press(PointOption.point(width/2, height/4)).waitAction(WaitOptions.waitOptions(duration))
                .moveTo(PointOption.point(width/2, height*3/4)).release();
        action.perform();
    }
    /**
     *向左滑動操作
     */
    public void swipeToLeft(AndroidDriver driver) {
        int width = driver.manage().window().getSize().width;
        int height = driver.manage().window().getSize().height;
        TouchAction action=new TouchAction(driver).press(PointOption.point(width*3/4, height/2)).waitAction(WaitOptions.waitOptions(duration))
                .moveTo(PointOption.point(width/4,height/2)).release();
        action.perform();
    }
    /**
     *向右滑動操作
     */
    public void swipeToRight(AndroidDriver driver) {
        int width = driver.manage().window().getSize().width;
        int height = driver.manage().window().getSize().height;
        TouchAction action=new TouchAction(driver).press(PointOption.point(width / 4, height / 2)).waitAction(WaitOptions.waitOptions(duration))
                .moveTo(PointOption.point(width*3/4,height/2)).release();
        action.perform();
    }

    /*=====================通過具體坐标點選操作,appium&&adb兩種方式==================================*/
    /**
     * 通過具體坐标點選
     */
    public void taptest(AndroidDriver driver,int x, int y){
        /**設定顯示等待時間10s  driver=baseAndroidDriver.getDriver(baseConfig)
        特注:顯示等待與隐式等待相對,顯示等待必須在每一個需要等待的元素前面進行聲明,如果在規定的時間内找到元素,則直接執行,即找到元素就執行相關操作
         */
        wait = new WebDriverWait(driver,5);
        //tap點選坐标,輸入坐标,然後再release()釋放坐标點,用perform()去執行一系列action操作
        action = new TouchAction(driver).tap(PointOption.point(x,y)).release().perform();

    }
    /**
     * 通過adb指令驅動被測裝置
     */
    public void adbInput(AndroidDriver driver ,String input){
        try {
            Process process = Runtime.getRuntime().exec(input);
            wait = new WebDriverWait(driver,5);
            process.destroy();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
           
  • page包(通用PO模式):分為data資料包和element元素操作包,把定位元素和輸入框資料統一放到data包中,元素的操作放到element包中。其中元素的操作資料來源于data包中。
    java版app自動化測試初始化模闆
  • testcase包是根據業務流程編寫用例步驟(後面的用例維護均在此包下)
    java版app自動化測試初始化模闆
  • resource包下可以放chromedriver驅動或者存放異常捕獲的截圖、測試報告自動生成index.html報告(由于使用springboot可以直接通路報告)另一種測試報告用的最多的是allure2,一個開源很好的報告模闆allure2 的GitHub位址測試報告輸出到allure-results包下。
    java版app自動化測試初始化模闆
  • allure2報告內建,win下需要先下載下傳allure2的zip包GitHub官網下載下傳位址allure2,下載下傳zip包後需要配置下環境變量,用例執行完成後會生成allure-results檔案夾,在目前檔案夾下執行
allure serve allure-results
           

即可自動打開web測試報告,如下:

java版app自動化測試初始化模闆
  • extentreports報告樣式如圖(這裡把項目源碼路徑修改了下,需要單獨導下包,具體見接口自動化測試文章介紹)
    java版app自動化測試初始化模闆
    該項目源碼位址

模闆流程說明

  • 1、先在testcase包内寫測試用例流程,testcase包下的類需要繼承BaseTest 來擷取driver驅動

    eg:

public class YynCases extends BaseTest {
    /**
     * 測試示例用例,繼承BaseTest擷取driver驅動
     * 操作層
     */
    EnterYynElemnt enterMiniElemnt = new EnterYynElemnt();
    public void getDriverCase(){
        System.out.println(driver);
       //點選彈框按鈕
        enterMiniElemnt.popupClick(driver);
    }
}
           
  • 2、建立page包下的element包中的元素操作類,即:EnterYynElemnt 類此包下的類需要繼承BaseApp類來擷取封裝的公共操作方法。
@Slf4j
public class EnterYynElemnt extends BaseApp{
    /**
     * 繼承BaseApp使用公共封裝方法
     * */
    //點選彈框
    public void popupClick(AndroidDriver driver) {
        //使用封裝By類型元素定位,且資料和元素分離
        log.info("點選彈框");
        clickButton( driver, PopupData.POPUP1);
    }
}
           
  • 3、建立page包下的data包的定位資料或者是輸入框資料,所有的元素定位和輸入資料均在此包下維護。上面參數POPUP1通過id定位,PopupData類下的POPUP1資料如下:
public class PopupData {
    //更新彈框
    public static final By POPUP1= By.id("com.tengyun.yyn:id/layout_confirm_cancel");
    //第二個彈框
    public static final By POPUP2 = By.id("com.tengyun.yyn:id/layout_activity_cancel");
           
  • 4、其中第二步使用的是BaseApp封裝的公共類方法clickButton
public WebElement clickButton(AndroidDriver driver,By locator) {
        try {
            long time1 = DateUtils.getCurrentMillisecond();
            MobileElement buttonElement = (MobileElement) locateElement(driver,locator);
            wait.until(ExpectedConditions.elementToBeClickable(locator));
            if (buttonElement.isEnabled()){
                buttonElement.click();
                log.info("該點選事件耗時時間(ms):"+(DateUtils.getCurrentMillisecond()-time1));
                return buttonElement;
            }
        } catch (NoSuchElementException | TimeoutException e) {
            System.out.println("================目前頁面未捕獲該元素,截圖保留>>>>繼續執行用例==================");
            ScreenshotUtil.snapshot(driver);
        }
        return null;
//       System.out.println("改點選事件耗時時間(ms):"+(DateUtils.getCurrentMillisecond()-time1));
    }
           

輸入框輸入資料方法也是很常用的

public WebElement sendInput(AndroidDriver driver,By locator, CharSequence... content) {
        WebElement inputElement = locateElement(driver,locator);
        inputElement.clear();
        inputElement.sendKeys(content);
        return inputElement;
    }
           
  • 5、最後可以統一把testcase包下的類放到testNG的入口中執行測試并生成報告(由于使用springboot架構沒有用testNG的xml配置,而是通過封裝方法進行配置)
/**
 * 測試用例總入口
 * */
   @Test
    public void runCases(){
        //執行測試用例入口
        BaseTestngInit baseTestngInit = new BaseTestngInit();
        baseTestngInit.baseTestngInitCode();
    }
           

testNG封裝的工具類BaseTestngInit(工具類中也可以通過testng.xml初始化testng,具體看個人使用習慣)

/**
     * 初始化testng
     */
    public  void baseTestngInitCode()  {
        //建立testng對象
        TestNG testng = new TestNG();
        //建立報告監聽器對象
        ExtentTestNGIReporterListener reportListener = new ExtentTestNGIReporterListener();
//        TestLogListener testLogListener = new TestLogListener();
        //設定需要執行的測試用例類
        testng.setTestClasses(new Class[] { com.iappium.testcase.YynCases.class});
        //添加監聽器
        testng.addListener(reportListener);
//        testng.addListener(testLogListener);
        //運作測試
        testng.run();
    }
           

點選可擷取該項目源碼位址

更多測試技術分享、學習資源以及一些其他福利可關注公衆号:【Coding測試】擷取: