接到一个android自己主动化的任务,看了看手中的家伙:ranorex,appium,uiautomator

当然先捡商用的试试,简单呀,能够录制回放,只是不是抱特别大的期望,这个爷比較娇气,要是androidproject中有第三方库可能就会instrument失败。这次运气不错,instrument成功了,录制了一下经常使用的操作,一切OK。想想还要准备一些啥:

先说手势:搜搜帮助:

public void Swipe(

Location startLocation,

GestureDirection direction,

int distance,

Duration swipeDuration,

int steps

)


好吧,照抄写一个函数出来,留着备用:

public void myUp2Down(string argument1)

{

int iparam1=Convert.ToInt32(argument1);

for (int i=1;i<=iparam1;i++){

Report.Log(ReportLevel.Info, "Touch Gestures", "Swipe gesture with direction 'Up (270°)' starting from 'Center' with distance '100' with swipe duration'500ms' and step count '0' on item 'ComWumiiAndroidMimi.ListView'.", repo.xxx.ListViewInfo, new RecordItemIndex(1));

repo.xxx.ListView.Swipe(Location.Center, 270, 100, 500, 4);

Delay.Milliseconds(500);

}

}

这个凝视已经说的非常清楚了,就是从下往上滑动,270度是向上,180度是左面,0度是右面,90度是以下。100是距离,500是持续时间,4是步骤

拷屏:

pc:

Report.Screenshot();

android手机:

Report.Screenshot(ReportLevel.Info, "User", "", repo.xx.Self, false);

Report.Screenshot(ReportLevel.Info, "User", "", repo.xx.MyHomeActivity, false);

都是数据仓库中的对象,非常easy吧

再往下做的时候,发现一个问题,ranorex不能跨应用,而这个被測程序要分享给什么微信,新浪微博一类的。得,换刀。

用啥呢,appium是最全面的,就他吧。開始的时候总是非常愉快的:

拷屏:

public static void takeScreenShot(WebDriver driver,String s1)

{

File screenShotFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);

try {

FileUtils.copyFile(screenShotFile, new File(s1));

}

catch (IOException e) {e.printStackTrace();}

}

public static String getCurrentDateTime(){

SimpleDateFormat df = new SimpleDateFormat("HHmmss");//yyyyMMddHHmmss

return df.format(new Date());

}

调用方法:

private WebDriver driver;

takeScreenShot(driver,"/sdcard/"+getCurrentDateTime()+"main.png");

暴力等待:

public void mysleep(int i1){

try {

Thread.sleep(i1);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

调用:等待5s:mysleep(5000);

想想,要是能够用控件id引用,不是来的直接可靠得多。好像真机上hierarchyviewer.bat(D:\Android\android-sdk\tools)抓不到布局,用模拟器试试,提醒如今是monitor.bat时代了,直接使用管理员权限打开monitor.bat(右键该文件,选择管理员权限启动)。启动模拟器,等了半天,总算得到了布局文件,是不是一大堆东西,没事,仅仅须要点击到几个主干节点上,就能够看到这几个节点所相应的元素图片,非常easy找到吧,还能够用来调优哟,留心看看有个三个圆圈的button,会显示每一个view的载入时间。

然后非常悲剧的,花了非常长时间才试出来怎样引用id:

//WebElement el = driver.findElement(By.id("btnImsi")); //error

//WebElement el = driver.findElement(By.id("@+id/btnImsi")); //error

//WebElement el = driver.findElement(By.id("id/btnImsi")); //error

//WebElement el = driver.findElement(By.id("1")); //error

//WebElement el = driver.findElement(By.id("汉字一")); //error

WebElement el = driver.findElement(By.id("com.example.aimsi:id/btnImsi")); //ok

el.click();

本来也算不错了,老是不停的切换真机和模拟器,hierarchyviewer这个破东西又慢的要死,中间又要启动appium.exe,并且要引用对象又要tagname,还得list里面去找时第几个,真是非常烦人,等待的策略也没搜到让人爽一点的。并且那个sendkey在这台机器上每次都是抽风状态的,发个123,他能输出个321,肚脐眼都能被气歪。

得,再次换刀,uiautomator但是google的亲生儿子,一开头就弄了一个下马威:

拷屏:死活不行,最终明确了,就俩字:版本号!

//for >=android4.2

public void TakeScreenShotsGE42(String s1) {

File storePath = new File(s1);

getUiDevice().takeScreenshot(storePath);

}

private void runShellCommand(String command) throws IOException, InterruptedException {

Process p = null;

BufferedReader resultReader = null;

try {

p = Runtime.getRuntime().exec(command);

int status = p.waitFor();

if (status != 0) {

throw new RuntimeException(String.format("Run shell command: %s, status: %s",

command, status));

}

} finally {

if (resultReader != null) {

resultReader.close();

}

if (p != null) {

p.destroy();

}

}

}

//for <android4.2

public void TakeScreenShotsL42(String s1) {

// adb shell screencap -p /data/local/tmp/screen-capture.png

// adb pull /data/local/tmp/screen-capture.png <localfile.png>

// adb shell rm /data/local/tmp/screen-capture.png

try {

runShellCommand("screencap -p "+s1);

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

看到了吧,啥叫作孽,低版本号的就得去调用底层的命令行,高版本号的就俩句

调用方法就都差点儿相同:

import java.util.Date;

import java.text.SimpleDateFormat;

public String getNowPng(){

SimpleDateFormat df = new SimpleDateFormat("MMddHHmmss"); //yyyy-MM-dd HH:mm:ss

return "/sdcard/"+df.format(new Date())+".png";

}

TakeScreenShotsL42(getNowPng());

TakeScreenShotsGE42(getNowPng());

总算搞定了,看着有人说能够绕过那个破东西hierarchyviewer,能够在执行过程中保存实时布局,心下大爽,看,多简单呀,就这么两句:

public void dump(String s1) {

UiDevice uiDevice = getUiDevice();

uiDevice.dumpWindowHierarchy(s1);

}

调用也简单:dump(“d1.xml”);

会写入: /data/local/tmp文件夹,回头adb pull /data/local/tmp/d1.xml 拖下来就是了

理想黑丰满,现实超骨干,运行没报错,可是就是没生成,再次从真机(4.1.1)切换为模拟器(4.4.2),果然模拟器上运行正常,八成又是版本号问题。你妹的

再次尝试id引用:

UiObject ac1=new UiObject(new UiSelector().resourceId("com.xx.android.xxx:id/menu"));

哇,多爽呀,能够精确定位啦!大不了麻烦一点,先在模拟器中取得各个界面的布局文件,然后想操作那个对象都能够直接引用了,超级爽呀!

别整天做梦娶媳妇想得美了。这个也是高版本号才行!真是让人抓狂!

好了,迄今为止,uiautomator基本上是够用了,整理思路,能够这样,每次開始前删除指定文件夹的文件,回头每次动作都保存图片进去。对象的引用方法也别想id了,又不支持中文,contentDescription更没指望,直接classname加index来吧,没啥搞不定的。对象等待也简单统一写法。好,一样样的来说吧:

先删除sd卡中的一个文件夹:

public void deletefile(String s1)

{

File file =new File(s1);

File files[] = file.listFiles();

if (files != null) {

for (int i = 0; i < files.length; i++) { // 遍历文件夹下全部的文件

files[i].delete();

}

}

}

调用方法:deletefile("/sdcard/xxx/");

对象引用方法,直接ddms(留心看有个小图标:Dump View for hierarchyviewer UI Automator),你不会连ddms怎么打开都不会吧?(window-openperspective,假设有ddms就直接打开,没有就选择other…,这下总该看到了吧):

UiObject ac02_1 = new UiObject(new UiSelector().className(android.widget.LinearLayout.class.getName()).index(0));

UiObject ac02_2 = ac02_1.getChild(new UiSelector().className(android.widget.FrameLayout.class.getName()).index(0));

UiObject ac02_3 = ac02_2.getChild(new UiSelector().className(android.widget.ImageView.class.getName()).index(0));

你可能奇怪,为啥引用这么多层,原因是这种,当前页面中,有非常多ImageView,并且index都是0,你要是直接那么引用,就会有反复的ImageView,无法定位到唯一的对象,即便你加上了上一层的FrameLayout,index=0,也未必就是唯一的。这种引用方法非常是麻烦。可是唯一可靠,逻辑统一。

缺点吗,写出来的代码,我自己都看不出来是引用的啥对象。

就在已经差点儿相同结束的时候,又冒出来一个小插曲,共享给qqclient,没想到打开了一个老版本号的,竟然是webview,tnnd,uiautomator对付不了webview,无法引用到webview内部的对象,就算绝对定位后,点击了控件也没法输入username和password。事实上这样说是不公道的,UIAutomator是能够对付webview,只是,预计看官已经猜到了,又是你妹的高版本号就能够!咆哮!

我总不能又绕回来使用appium,江湖传言,Appium在4.1以上使用uiautomator, 4.1下面使用selendroid,而selendroid擅长这个东东。我去。

得,终于敲定方案:

大部分简单功能都用ranorex,简单有用才是王道;

共享部分使用uiautomator,亲生的比appium还是更简单一些。

Webview怎么搞?装一个client即可了,没兴趣花时间去为了这么点功能啃骨头。

同学们看着玩吧。

更多相关文章

  1. Android(安卓)C++的sp指针简介
  2. binder机制详解
  3. Android实际开发常用框架总结
  4. Android自动测试之monkeyrunner工具(一)
  5. Activity任务栈和亲属关系(Activities and Tasks)
  6. 检查Android本地代码的内存泄漏(Detecting memory leak in Androi
  7. GreenDao详解
  8. Android(安卓)开发进阶之『清除应用中的内存泄漏』
  9. Android开发者,是时候了解LeakCanary了

随机推荐

  1. Android的广播机制——Broadcast Reciver
  2. Android实现视频播放的3种实现方式
  3. 使用 Android 实现联网
  4. android中常用布局
  5. Android 秒级编译方案-Freeline安装使用
  6. Android(安卓)adapter中调用activity中的
  7. android基于tcpdump的数据包捕获完整解决
  8. Android适配(屏幕适配、国际化适配)
  9. Android(安卓): java.lang.UnsatisfiedLi
  10. android平台下基于MediaRecorder和AudioR