• appium安卓自动化的 常用driver方法封装


    appium安卓自动化的 常用driver方法封装 

    做安卓自动化的时候,很多方法写起来会造成代码冗余,把这部分封装起来 ,添加到androidUI工具类里,随时可调用

    都放在这个类下面:

    @Component
    public class AndroidUI{

    首先要进行driver实例的连接,连接后才能做相应的一些操作,及得造作完成要关闭driver,避免内存占用

    连接driver

    /*
    * @method: 连接driver
    */
    public void setUp(DesiredCapabilities dCapabilities) throws MalformedURLException {
    driver = new AndroidDriver<>(new URL("http://127.0.0.1:4723/wd/hub"), dCapabilities);
    logger.info(driver.currentActivity());
    }

    断开driver

    /*
    * @method: 断开driver
    */
    public void tearDown() throws Exception {
    if (null != driver) {
    driver.quit();
    }
    }

    休眠方法时间定义毫秒或秒都行吧,看个人喜好,我这里为了写着定义成秒的,系统自带是毫秒

    /*
    * @method: 休眠方法
    * @param: int seconds 休眠的时间,单位为s(必须大于等于1)
    * @other: Appium类内设置的所有操作方法均会在正常结束后休眠1s,无需在用例中手动休眠
    */
    public void sleep(int time) {
    if (!((time >= 1) && (time % 1 == 0))){
    Assert.fail("sleep: Parameter ERROR!");
    }
    try {
    Thread.sleep(time * 1000);
    //System.out.println("休息");
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }

    上面休眠方法是死的,而元素加载时间不确定的,可以用下面等待找到元素的灵活等待时间

    /*
    * @method: 比sleep更有客观的延迟方法,在一定时间内等待某元素在屏幕中出现。
    * @param: String target 等待的目标
    * int time 等待时间,单位为ms,必须是1的正整数倍
    * @other: Appium类内设置的所有操作方法均会在正常结束后休眠1s,无需在用例中手动休眠
    */
    public boolean waitFor(String target,int time) {

    try {
    if (!((time >= 1) && (time % 1 == 0))){
    Assert.fail("waitFor: Parameter ERROR!");
    }
    String result = null;
    String page = driver.getPageSource();
    logger.info("Waiting for " + target + " ...");

    for (int i = 1; i <= time; i++) {
    if (page.contains(target)) {
    result = "Succeeded.";
    logger.info(result);
    break;
    } else {
    sleep(1);
    page = driver.getPageSource();
    }
    }
    } catch (Exception e) {
    logger.error("元素:"+target+"不存在");
    sleep(1);
    e.printStackTrace();
    return false;
    }
    return true;
    }

    然后是滑动操作,这个操作是比较常用的手势,按照方向做了封装,调用时把方向作为参数使用
    /*
    * @method: 滑动操作
    * @param: String direction, right 向右四分之一/left 向左四分之一/up 向上四分之一/down 向下四分之一/top 到顶/end 到底
    */
    public void swipeTo(String direction) {

    int width=driver.manage().window().getSize().width;
    int height=driver.manage().window().getSize().height;


    if (direction == "right") {
    driver.swipe(width/4, height/2, width*3/4,height/2, 500);
    logger.info("右滑");
    } else if (direction == "left") {
    driver.swipe(width*3/4, height/2, width/4, height/2, 500);
    logger.info("左滑");
    } else if (direction == "down") {
    driver.swipe(width/2, height/4, width/2, height*3/4, 500);
    logger.info("下滑");
    } else if (direction == "up") {
    driver.swipe(width/2, height*3/4, width/2, height/4, 500);
    logger.info("上滑");
    } else if (direction == "end") {
    String page1;
    String page2;
    do {
    page1 = driver.getPageSource();
    driver.swipe(width/2, height*3/4, width/2, height/4, 500);
    sleep(2);
    page2 = driver.getPageSource();
    } while (!page1.equals(page2));
    logger.info("滑到底");
    } else if (direction == "top") {
    String page1;
    String page2;
    do {
    page1 = driver.getPageSource();
    driver.swipe(width/2, height/4, width/2, height*3/4, 500);
    sleep(4);
    page2 = driver.getPageSource();
    } while (!page1.equals(page2));
    logger.info("滑到顶");
    }
    sleep(1);
    }

    学过安卓开发的都知道,layout中有各种view、包括textView、imageView、Button、checkBox、radioButton、alertDialog、processDialog啥的
    所以对于这些的点击处理最好是根据id或text作为参数封装方法来进行定位点击操作
    例如:
    /*
    * @method: 通过想点击文字的控件id和顺序index点击文字,当第一屏未找到文字会向下滚动查找,若滚到底扔未发现文字断言失败;方法结束后休眠1s
    * @param: String id 想点击文字的id
    * int index 顺序
    */
    public void clickTextById(String id, int index) {

    String page1;
    String page2;
    int result = 0;

    do {
    page1 = driver.getPageSource();
    if (page1.contains(id)) {
    if (index == 0) {
    AndroidElement imageElement = driver.findElementByXPath("//android.widget.TextView[contains(@resource-id,'" + id + "')]");
    logger.info("Text " + id + " found.");
    imageElement.click();
    logger.info("Text " + id + " clicked.");
    result = 1;
    } else if (index > 0) {
    List<AndroidElement> imageElements = driver.findElementsByXPath("//android.widget.TextView[contains(@resource-id,'" + id + "')]");
    AndroidElement imageElement = imageElements.get(index);
    logger.info("Text " + id + " found.");
    imageElement.click();
    logger.info("Text " + id + " clicked.");
    result = 1;
    }
    break;
    } else {
    this.swipeTo("down");
    page2 = driver.getPageSource();
    }
    } while (!page1.equals(page2));

    if (result == 0) {
    Assert.fail("Clicking Text " + id + " failed.");
    }
    sleep(1);
    }

    当然,我们进行测试,是为了确定页面中有某元素或是没有某元素,所以用的最多的方法是search

    public void search(String list) {

    String pageSource = this.pageSource();
    if (!list.contains(",")) {
    if (pageSource.contains(list)) {
    logger.info(list + " is found.");
    } else {
    takeScreenShot("FAILURE(search)_" + list);
    Assert.fail("Searching " + list + " failed.");
    }
    } else {
    String elements[] = list.split(",");
    for (int i = 0; i <= ((elements.length)-1); i++) {
    if (elements[i].contains(" ")) {
    elements[i] = elements[i].trim();
    }
    if (pageSource.contains(elements[i])) {
    logger.info(elements[i] + " is found.");
    } else {
    takeScreenShot("FAILURE(search)_" + list);
    Assert.fail("Searching " + elements[i] + " failed.");
    }
    }
    }
    sleep(1);
    }

    上面要说明一下。
    takeScreenShot("FAILURE(search)_" + list); 这个是单独写的截屏函数,
    这个方法在出现错误时,保存个截图到某一文件夹下更好,这样可以方便定位问题
    public void takeScreenShot(String methodName) {
    File srcFile = AndroidUI.driver.getScreenshotAs(OutputType.FILE);
    //利用FileUtils工具类的copyFile()方法保存getScreenshotAs()返回的文件对象。
    // FileUtils.copyFile(srcFile, new File("screenshot.png"));
    String fileName = methodName + "_" + DateUtil.formatNowTime(12) + ".png";
    String filePath = "C:\Users\linyuchen\Pictures\AndroidUI";
    try {
    FileUtils.copyFile(srcFile, new File(filePath+"\"+fileName));
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    // System.out.println("taking ScreenShots");

    }

    其实还有很多很多方法 ,大家可以根据自己喜好来定义 都可以随意些
    
    
  • 相关阅读:
    思科交换机命令
    Cisco2960 交换机密码破解方法
    洛谷 P2147 [SDOI2008]洞穴勘测
    BZOJ 4025: 二分图
    算法笔记--可撤销并查集 && 可持久化并查集
    P5043 【模板】树同构([BJOI2015]树的同构)
    算法笔记--BSGS && exBSGS 模板
    算法笔记--线性基求交模板
    AcWing 246. 区间最大公约数
    2018年长沙理工大学第十三届程序设计竞赛 I 连续区间的最大公约数
  • 原文地址:https://www.cnblogs.com/linyuchen2008/p/8440965.html
Copyright © 2020-2023  润新知