zoukankan      html  css  js  c++  java
  • 手机自动化测试:appium源码分析之bootstrap五

    手机自动化测试:appium源码分析之bootstrap五

     

          poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标。poptest测试开发工程师就业培训请大家咨询qq:908821478)移动端自动化测试是未来的测试工程师的技术要求,我们需要打好基础。

         

    Swipe代码:

    package io.appium.android.bootstrap.handler;

    import com.android.uiautomator.core.UiDevice;

    import com.android.uiautomator.core.UiObjectNotFoundException;

    import io.appium.android.bootstrap.*;

    import io.appium.android.bootstrap.exceptions.InvalidCoordinatesException;

    import io.appium.android.bootstrap.utils.Point;

    import org.json.JSONException;

    import java.util.Hashtable;

    /**

     * This handler is used to swipe.

     *

     */

    public class Swipe extends CommandHandler {

      /*

       * @param command The {@link AndroidCommand} used for this handler.

       *

       * @return {@link AndroidCommandResult}

       *

       * @throws JSONException

       *

       * @see io.appium.android.bootstrap.CommandHandler#execute(io.appium.android.

       * bootstrap.AndroidCommand)

       */

      @Override

      public AndroidCommandResult execute(final AndroidCommand command)

          throws JSONException {

        final Hashtable<String, Object> params = command.params();

        final Point start = new Point(params.get("startX"), params.get("startY"));

        final Point end = new Point(params.get("endX"), params.get("endY"));

        final Integer steps = (Integer) params.get("steps");

        final UiDevice device = UiDevice.getInstance();

        Point absStartPos = new Point();

        Point absEndPos = new Point();

        if (command.isElementCommand()) {

          try {

            final AndroidElement el = command.getElement();

            absStartPos = el.getAbsolutePosition(start);

            absEndPos = el.getAbsolutePosition(end, false);

          } catch (final UiObjectNotFoundException e) {

            return getErrorResult(e.getMessage());

          } catch (final InvalidCoordinatesException e) {

            return getErrorResult(e.getMessage());

          } catch (final Exception e) { // handle NullPointerException

            return getErrorResult("Unknown error");

          }

        } else {

          try {

            absStartPos = getDeviceAbsPos(start);

            absEndPos = getDeviceAbsPos(end);

          } catch (final InvalidCoordinatesException e) {

            return getErrorResult(e.getMessage());

          }

        }

        Logger.debug("Swiping from " + absStartPos.toString() + " to "

            + absEndPos.toString() + " with steps: " + steps.toString());

        final boolean rv = device.swipe(absStartPos.x.intValue(),

            absStartPos.y.intValue(), absEndPos.x.intValue(),

            absEndPos.y.intValue(), steps);

        if (!rv) {

          return getErrorResult("The swipe did not complete successfully");

        }

        return getSuccessResult(rv);

      }

    }

    先分析源码:

    final Hashtable<String, Object> params = command.params();
    final Point start = new Point(params.get("startX"), params.get("startY"));
    final Point end = new Point(params.get("endX"), params.get("endY"));
    final Integer steps = (Integer) params.get("steps");
    final UiDevice device = UiDevice.getInstance();

        Point absStartPos = new Point();
        Point absEndPos = new Point();

    首先从命令里获取参数,后解析出3个变量:起始点start、终点end、步骤steps。然后获得设备对象,定义2个私有Point对象,以备后用。
    然后分条件处理,处理控件还是处理坐标。

    控件:

    final AndroidElement el = command.getElement();
    absStartPos = el.getAbsolutePosition(start);
    absEndPos = el.getAbsolutePosition(end, false);

    首先获取控件对象,再通过getAbsolutePosition传入不同的参数获得在该控件上点击的起始点和结束点。

    public Point getAbsolutePosition(final Point point,

          final boolean boundsChecking) throws UiObjectNotFoundException,

          InvalidCoordinatesException {

        final Rect rect = el.getBounds();

        final Point pos = new Point();

        Logger.debug("Element bounds: " + rect.toShortString());

        if (point.x == 0) {

          pos.x = rect.width() * 0.5 + rect.left;

        } else if (point.x <= 1) {

          pos.x = rect.width() * point.x + rect.left;

        } else {

          pos.x = rect.left + point.x;

        }

        if (boundsChecking) {

          if (pos.x > rect.right || pos.x < rect.left) {

            throw new InvalidCoordinatesException("X coordinate ("

                + pos.x.toString() + " is outside of element rect: "

                + rect.toShortString());

          }

        }

        if (point.y == 0) {

          pos.y = rect.height() * 0.5 + rect.top;

        } else if (point.y <= 1) {

          pos.y = rect.height() * point.y + rect.top;

        } else {

          pos.y = rect.left + point.y;

        }

        if (boundsChecking) {

          if (pos.y > rect.bottom || pos.y < rect.top) {

            throw new InvalidCoordinatesException("Y coordinate ("

                + pos.y.toString() + " is outside of element rect: "

                + rect.toShortString());

          }

        }

        return pos;

      }

    上面的代码首先分析x坐标然后分析y坐标。x和y坐标的判断和处理时一样的

    首先判断x坐标是否为0,如果为0,定义初始点的x坐标为控件的中心点的横坐标。如果x的坐标小于1,说明坐标为相对坐标,用百分比来求值,此时就要与宽度做乘积运算得到具体值。如果上面2种情况都不符合,那就是具体坐标值,那就直接元素的x坐标值加上控件的边框左坐标值。
    最后根据传入的boolean值来判断是否做一个超出边界的验证。如果超出边界就跑出异常。y坐标的获取方式类似。最后得到坐标值并返回,回到execute方法中。

    坐标

    absStartPos = getDeviceAbsPos(start);
    absEndPos = getDeviceAbsPos(end);

    通过调用getDeviceAbsPos()方法得到坐标值来初始化之前声明的私有Point对象.

    protected static Point getDeviceAbsPos(final Point point)

          throws InvalidCoordinatesException {

        final UiDevice d = UiDevice.getInstance();

        final Point retPos = new Point(point); // copy inputed point

        final Double width = (double) d.getDisplayWidth();

        if (point.x < 1) {

          retPos.x = width * point.x;

        }

        if (retPos.x > width || retPos.x < 0) {

          throw new InvalidCoordinatesException("X coordinate ("

              + retPos.x.toString() + " is outside of screen "

              + width.toString());

        }

        final Double height = (double) d.getDisplayHeight();

        if (point.y < 1) {

          retPos.y = height * point.y;

        }

        if (retPos.y > height || retPos.y < 0) {

          throw new InvalidCoordinatesException("Y coordinate ("

              + retPos.y.toString() + " is outside of screen height: "

              + height.toString());

        }

        return retPos;

      }

    类似于上面的方法,也是要先判断传过来的坐标值是否小于1,如果小于1,当作百分比来球坐标值。如果超出屏幕的范围抛出异常,最后返回坐标值回到execute方法。

    final boolean rv = device.swipe(absStartPos.x.intValue(),
    absStartPos.y.intValue(), absEndPos.x.intValue(),
    absEndPos.y.intValue(), steps);

    最后调用UiDevice.swipe方法来执行命令,判断是否执行成功。

    总结
    执行swipe命令有2中命令格式
    a.控件
    b.坐标
    坐标又分为相对坐标百分比和绝对坐标两种方法。

  • 相关阅读:
    JavaScript在web自动化测试中的作用
    Python使用Pandas高效处理测试数据
    git update-index --assume-unchanged忽略跟踪
    git reset三种模式
    Python Unittest根据不同测试环境跳过用例详解
    python ddt 实现数据驱动
    测试用例重要性暨动端测试用例设计总结
    jenkins执行selenium自动化测试浏览器不显示解决方法
    《过目不忘的读书法》 读书笔记
    memcached 学习
  • 原文地址:https://www.cnblogs.com/poptest/p/4949905.html
Copyright © 2011-2022 走看看