手机自动化测试:appium源码分析之bootstrap六
poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标。poptest测试开发工程师就业培训请大家咨询qq:908821478)移动端自动化测试是未来的测试工程师的技术要求,我们需要打好基础。
Flick
package io.appium.android.bootstrap.handler;
import com.android.uiautomator.core.UiDevice;
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 flick elements in the Android UI.
*
* Based on the element Id, flick that element.
*
*/
public class Flick extends CommandHandler {
private Point calculateEndPoint(final Point start, final Integer xSpeed,
final Integer ySpeed) {
final UiDevice d = UiDevice.getInstance();
final Point end = new Point();
final double speedRatio = (double) xSpeed / ySpeed;
double xOff;
double yOff;
final double value = Math.min(d.getDisplayHeight(), d.getDisplayWidth());
if (speedRatio < 1) {
yOff = value / 4;
xOff = value / 4 * speedRatio;
} else {
xOff = value / 4;
yOff = value / 4 / speedRatio;
}
xOff = Integer.signum(xSpeed) * xOff;
yOff = Integer.signum(ySpeed) * yOff;
end.x = start.x + xOff;
end.y = start.y + yOff;
return end;
}
/*
* @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 {
Point start = new Point(0.5, 0.5);
Point end = new Point();
Double steps;
final Hashtable<String, Object> params = command.params();
final UiDevice d = UiDevice.getInstance();
if (command.isElementCommand()) {
AndroidElement el;
try {
el = command.getElement();
start = el.getAbsolutePosition(start);
final Integer xoffset = (Integer) params.get("xoffset");
final Integer yoffset = (Integer) params.get("yoffset");
final Integer speed = (Integer) params.get("speed");
steps = 1250.0 / speed + 1;
end.x = start.x + xoffset;
end.y = start.y + yoffset;
} catch (final Exception e) {
return getErrorResult(e.getMessage());
}
} else {
try {
final Integer xSpeed = (Integer) params.get("xSpeed");
final Integer ySpeed = (Integer) params.get("ySpeed");
final Double speed = Math.min(1250.0,
Math.sqrt(xSpeed * xSpeed + ySpeed * ySpeed));
steps = 1250.0 / speed + 1;
start = getDeviceAbsPos(start);
end = calculateEndPoint(start, xSpeed, ySpeed);
} catch (final InvalidCoordinatesException e) {
return getErrorResult(e.getMessage());
}
}
steps = Math.abs(steps);
Logger.debug("Flicking from " + start.toString() + " to " + end.toString()
+ " with steps: " + steps.intValue());
final boolean res = d.swipe(start.x.intValue(), start.y.intValue(),
end.x.intValue(), end.y.intValue(), steps.intValue());
if (res) {
return getSuccessResult(res);
} else {
return getErrorResult("Flick did not complete successfully");
}
}
}
代码的步骤和swipe类似,而且最终调用的也是UiDevice.swipe方法,那么我们来看看到底区别在什么地方。首先它也分控件和坐标,分别分析:
控件
首先将控件的中心点作为起始坐标,然后根据提供的参数xoffset和yoffset来获取位移数据,speed参数用来计算步骤。
steps = 1250.0 / speed + 1;
end.x = start.x + xoffset;
end.y = start.y + yoffset;
起始坐标加上位移就是结束坐标,这个steps的设置还是有点让人摸不着头脑的,我这个1250我且认为是最大位移吧,speed代表每一步走的路程。用1250/speed得到使用多少步到结束点,再加上初始值的那个点就得到steps的值啦。至此起始点坐标、结束点坐标、步骤的值都设置完毕。
坐标
严格来说,不能说成坐标,应该算坐标位移,因为才传入的参数其实坐标系的速度xSpeed和ySpeed。x轴移动xSpeed距离,y轴移动ySpeed坐标。然后获取坐标值和steps值。
其中它用1250和位移的平方做了一次比较,取出最小值来计算steps。起始坐标点定位屏幕的中心点坐标。然后再调用end = calculateEndPoint(start, xSpeed, ySpeed);方法获取结束点坐标。
private Point calculateEndPoint(final Point start, final Integer xSpeed,
final Integer ySpeed) {
final UiDevice d = UiDevice.getInstance();
final Point end = new Point();
final double speedRatio = (double) xSpeed / ySpeed;
double xOff;
double yOff;
final double value = Math.min(d.getDisplayHeight(), d.getDisplayWidth());
if (speedRatio < 1) {
yOff = value / 4;
xOff = value / 4 * speedRatio;
} else {
xOff = value / 4;
yOff = value / 4 / speedRatio;
}
xOff = Integer.signum(xSpeed) * xOff;
yOff = Integer.signum(ySpeed) * yOff;
end.x = start.x + xOff;
end.y = start.y + yOff;
return end;
}
首先计算位移比speedRatio(x的位移/y的位移),然后获取屏幕宽和高中最小的一个数复制给value.如果speedRatio<1,x的移动距离为value的值的1/4.y坐标为和x移动的距离是一样的。所以经过上面的计算得到的结束点的坐标和起始点组成的应该是正方型的对角线。
最后调用UiDevice.swipe和Swipe中是一样的啦。没什么特别的