手把手教你_android自己主动化实践方案选型

手把手教你_android自己主动化实践方案选型

大家好,又见面了,我是全栈君,祝每个程序员都可以多学几门语言。

 

 

接到一个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即可了,没兴趣花时间去为了这么点功能啃骨头。

 

 

 同学们看着玩吧。

 

 

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/118197.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • springboot+maven 项目 打jar包之后部署并启动方式「建议收藏」

    springboot+maven 项目 打jar包之后部署并启动方式「建议收藏」1、不管如何先clean下清掉之前的,命令:mvnclean。2、然后利用mvnpackage-DskipTests打出jar包。3、利用工具将jar包上传到linux服务器上面对应的位置。4、之前如果部署过的话先用命令ps-ef|grepjava看下进程,然后再利用kill-9把这个进程干掉。5、最后在利用命令nohupjava-jar…

  • EtherCAT总线通信Freerun、SM、DC三种同步模式分析

    EtherCAT总线通信Freerun、SM、DC三种同步模式分析EtherCAT总线三种同步模式分析一、分布式时钟作用使所有EtherCAT设备使用相同的系统时间,从而控制各设备任务的同步执行。二、名词解析1、 现场总线高速数据传递:即主站周期的向从站发送输出信息并周期地读取从站的输入信息2、 OutputValid:输出有效,指的是主站输出有效,表示的是从站将数据帧中对应数据从同步管理器通道上下载下来的一个过程。3、 InputLatch…

  • PLSQLDeveloper安装与配置

    PLSQLDeveloper安装与配置1,首先要有oracle数据库或者有oracle服务器,才可以实现使用PLSQLDeveloper工具连接到oracle数据库进行开发.2,下载PLSQLDeveloper并解压3,配置环境变量1)变量名:ORACLE_HOME变量值:E:\tool_01\PLSQLDeveloper\instantclient_11_22)变量名:TNS_ADMIN变量值:E:\tool_01…

  • 你要偷偷学python(所有人都能学的数据分析课)

    标题无意冒犯,就是觉得这个广告挺好玩的上面这张思维导图喜欢就拿走,反正我也学不了这么多文章目录前言欢迎来到我们的圈子并发与串行前言前期回顾:我要偷偷学Python(第十二天)第十二篇的项目还在持续更新中,哎,日理万机虽然谈不上,但是也是手忙脚乱。这不,自动表单生成是写完了,但是学校网络实在是受不了啊,2G,测试不了,就只能一直搁置在那边了。明天就可以去测试了,明天出学校去逛逛。今天的内容,可能很多小伙伴会没有听过,今天要讲多线程的概念,以及协程的使用。后面看看能不能讲一下scrapy框架..

  • 多重继承

    多重继承

  • 如何区别标准POE交换机和非标POE交换机[通俗易懂]

    如何区别标准POE交换机和非标POE交换机[通俗易懂]通俗的说,POE交换机就是支持网线供电的交换机,其不但可以实现普通交换机的数据传输功能还能同时对网络终端进行供电。那么,我们该如何来区别如何区别标准POE交换机和非标POE交换机呢?接下来我们就跟随飞畅科技的小编一起来详细看看吧!一、什么是POE交换机PoE供电交换机是指能够通过网线为远端受电终端提供网络供电的交换机,包含网络交换机和PoE供电两个功能,是PoE供电系统中比较常见的供电设备。二、POE交换机的分类1、标准POE交换机符合IEEE802.3af、802.3at标准,就是标准P..

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号