Appium 常用API
Appium定位的技巧还需要自己多多练习实践,单凭我这一篇教程远远不足解决你实际中遇到的元素定位问题,我想强调的是,一定要自己动手尝试,元素定位也要有自己的思路,一般需要和Dev协商一些规则,不但能规范开发也能方便测试。今天我们了解一下那些对APP操作的API,如(上下左右)滑动,长按,放大,缩小等内容,写一个滑动解锁的脚本作为参考。 阅读此文需要10分钟,更需要之前内容的基础,如果你没有阅读之前的教程,请在菜单中点击往期精彩。
Appium常用的手势操作API
- swipe --- 滑动
- zoom --- 放大
- pinch ---缩小
- tap --- 轻击
- scroll ----滚动(Deprecated)从4.0开始,scrollTo和scrollToExactbecame deprecated ,4.10中已经移除。本文不再给解释。
swipe 详解
相信大多数时间我们所使用的手势都是滑动,因为大多数APP基本都有滑动的手势, 比如安装好的APP出现引导页,列表内容单页不够显示,而滑动是一个比较友好的方式。
下面是swipe方法的原型
void swipe(int startx, int starty, int endx, int endy, int duration);
swipe方法共有五个参数,其中参数依次代表起始点x、y坐标,终点x、y坐标和滑动时间,单位毫秒。 如果想滑的快,就把时间设置小,反之。
swipe方法的原理解读
swipe方法的本质是封装TouchAction,通过touchAction先按下起始点坐标,再间隔时间之后移动到终点坐标并释放。
protected void doSwipe(int startx, int starty, int endx, int endy, int duration) {
TouchAction touchAction = new TouchAction(this);
touchAction.press(startx, starty).waitAction(duration).moveTo(endx, endy).release();
touchAction.perform();
}
小技巧
swipe 的高级用法,swipe 可以进一步封装,比如一些MobileElement需要滑动屏幕才能出现,这个时候就可以封装一个滚动到这些MoblieElement出现为止的方法。
zoom方法详解
zoom 方法是拉伸放大的手势,用到图片放大,页面放大。
void zoom(WebElement el);
void zoom(int x, int y);
zoom方法有两个,一个是传入一个WebElement,另外一个传入起始点坐标
zoom方法原理解读
zoom(x,y) 方法其实是由两个 MultiTouchAction实现的 首先根据你传入的坐标点确定偏移量,然后创建两个Action分别相反方向移动,同时间释放。
public void zoom(int x, int y) {
MultiTouchAction multiTouch = new MultiTouchAction(this);
int scrHeight = manage().window().getSize().getHeight();
int yOffset = 100;
if (y - 100 < 0) {
yOffset = y;
} else if (y + 100 > scrHeight) {
yOffset = scrHeight - y;
}
TouchAction action0 = new TouchAction(this).press(x, y).moveTo(0, -yOffset).release();
TouchAction action1 = new TouchAction(this).press(x, y).moveTo(0, yOffset).release();
multiTouch.add(action0).add(action1);
multiTouch.perform();
}
小提示
另外一个zoom方法也类似,可自己研究一下。传入的是一个元素,对元素进行操作。
pinch方法详解
pinch 与zoom做的事情刚好相反,都有两个方法。
void pinch(WebElement el);
void pinch(int x, int y);
Demo APK下载地址
demo所使用的APK
https://github.com/tobecrazy/appiumDemo/raw/master/apps/Locker.apk
swipe封装
还可以进一步封装滑动到某MobleElement 出现 举个例子,向上滑动屏幕 :
/**
* This Method for swipe up
*
* @author Young
* @param driver
* @param during
*/
public void swipeToUp(AndroidDriver<MobileElement> driver, int during)
{ int width = driver.manage().window().getSize().width;
int height = driver.manage().window().getSize().height;
driver.swipe(width / 2, height * 3 / 4, width / 2, height / 4, during);
}
核心代码如下
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.testng.Assert;
import org.testng.annotations.Test;
import io.appium.java_client.MobileElement;
import io.appium.java_client.TouchAction;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.remote.AndroidMobileCapabilityType;
import io.appium.java_client.remote.AutomationName;
import io.appium.java_client.remote.MobileCapabilityType;
import java.io.File;
import java.net.URL;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class unlockerTest {
private AndroidDriver<MobileElement> driver;
@Test
public void Demo() throws Exception {
// set up appium
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, AutomationName.APPIUM);
// for native app set null, for web test please set chrome or firefox
capabilities.setCapability(CapabilityType.BROWSER_NAME, "");
capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "Android Emulator");
// simulator version 4.4
capabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, "4.4");
// if no need install don't add this
File classpathRoot = new File(System.getProperty("user.dir"));
File appDir = new File(classpathRoot, "apps");
File app = new File(appDir, "Locker.apk");
capabilities.setCapability(MobileCapabilityType.APP, app.getAbsolutePath());
// package name
capabilities.setCapability(AndroidMobileCapabilityType.APP_PACKAGE, "com.AppiumGirls.locker");
// // support Chinese
capabilities.setCapability("unicodeKeyboard", "True");
capabilities.setCapability("resetKeyboard", "True");
// no need sign
capabilities.setCapability("noSign", "True");
// launcher activity
capabilities.setCapability(AndroidMobileCapabilityType.APP_ACTIVITY, ".MainActivity");
String url = "http://localhost:4723/wd/hub";
driver = new AndroidDriver<MobileElement>(new URL(url), capabilities);
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
MobileElement button = driver.findElementByAndroidUIAutomator("new UiSelector().text(\"设置手势密码\")");
// tap
button.tap(1, 1000);
// get all the items of gesture locker
List<MobileElement> items = driver.findElementsByClassName("android.widget.ImageView");
for (MobileElement item : items) {
/**
* 0 1 2 3 4 5 6 7 8
*/
item.click();
}
// create a Z from 0->1->2->4->6->7->8
TouchAction touches1 = new TouchAction(driver);
touches1.press(items.get(0)).waitAction(1000).moveTo(items.get(1)).waitAction(1000).moveTo(items.get(2))
.waitAction(1000).moveTo(items.get(4)).moveTo(items.get(6)).waitAction(1000).moveTo(items.get(7))
.waitAction(1000).moveTo(items.get(8)).release();
touches1.perform();
Thread.sleep(2000);
//create 0->1->2
TouchAction touches2 = new TouchAction(driver);
touches2.press(items.get(0)).waitAction(1000).moveTo(items.get(1)).waitAction(1000).moveTo(items.get(2))
.waitAction(1000).moveTo(items.get(4)).release();
touches2.perform();
MobileElement alert =driver.findElementById("com.AppiumGirls.locker:id/text_tip");
Assert.assertTrue(alert.getText().contains("与上一次绘制不一致,请重新绘制"));
}
}
✅运行结果如下:
总结
本章我们都学习了常见API的使用方法以及高级用法:
- swipe
- tap
- zoom
- pinch