• 13.UiAutomator 辅助APK的使用


    一、在测试中弹出提示框

    UiAutomator无法直接实现,,但是可以通过让辅助APK接受UiAutomator发送的指令信息来实现,使用am命令

    • 实例:
    1.新建辅助apk,用来接收Uiautomator用例中的广播信息(新建android appliction project,然后next直到finish为止,注意创建过程中选对API)
    2.建好工程后将一些不用的代码删除,需要删除的代码如下:
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
    3.然后在生成的辅助apk的src下的包中新建一个类作为广播接收器,继承”BroadcastReceiver”,代码如下:
    import android.app.AlertDialog.Builder;
    import android.app.Dialog;
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    import android.os.Bundle;
    import android.view.WindowManager;
    //注意上面的import文件。应该有这些导入就够了。之前调试过程中在Builder builder=new Builder(arg0);总是会报错。后来解决掉才发现原来是导入文件的问题
    public class AlertRecevier extends BroadcastReceiver{
    
        @Override
        public void onReceive(Context arg0, Intent arg1) {
                //接收键值对
                Bundle bundle=arg1.getExtras();
                String message=bundle.getString("alert");
                //创建消息弹窗
                Builder builder=new Builder(arg0);
                builder.setTitle("APP TEST");
                builder.setMessage(message);
                builder.setNegativeButton("OK",null);
                Dialog dialog=builder.create();
    
                dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
                dialog.show();
        }
    }
    4.代码编辑完成后,需要点辅助apk的.xml清单文件添加一个权限,

    1)在清单界面点”Permissions”–“add”–“uises-permission”–“ok”
    2)name=”android.permission.SYSTEM_ALERT_WINDOW” MaxSDK=20然后点add
    3)remove “uises-permission”
    4)点击xml清单文件查看是否有这个权限””
    5)在xml清单文件中注册广播接收器。也就是在结束标签后面加入下列代码

    </activity>//结束标签
    <receiver android:name="AlertRecevier">//name=广播接收器类名
        <intent-filter>
            <action android:name="jian.demo.action"/>//name=自定义
        </intent-filter>
    </receiver>

    6)右键点辅助APK工程–run as–android application,将apk安装到手机上
    7)打开命令行,输入命令”adb shell am broadcast -a [自定义的name] -e [广播接收器中定义的字符串] [可以随便输几个值]”查看是否注册成功,按照上述代码,该命令的正确表现形式应该是”adb shell am broadcast -a jian.demo.action -e alert 1234”

    5.在测试用例中写入以下代码:
    //弹出指定弹窗
    public void testDemo() throws IOException{
        alert("test alert!");
    }
    
    //写一个方法
    public void alert(String message) throws IOException{
        //自定义弹窗内容
        String cmd=("am broadcast -a jian.demo.action -e alert"+message);
        //输入命令
        try{
            Runtime.getRuntime().exec(cmd);
        }catch(IOException e){
            e.printStackTrace();
        }
    }

    二、在测试中输入中文

    UiObject.setText(String)这个API无法输入非ASCLL字符,比如中文、日文等,可以使用Unicode输入助手解决这个问题,它将输入的原始字符转换为Unicode文本,通过中间转化从而进行输入各种文字

    1.使用步骤:

    1)手机端安装jutf-7输入法
    2)将该输入法设置为手机默认输入法(系统设置–语言和输入法–设置UTF7为默认输入法)
    3)写用例过程中将UTF-7的辅助工具类加入进去
    4)使用”UiObject.setText(“Utf7lmeHelper.e(“各种语言”))”来实现各种语言的输入。

    2.UTF-7的辅助工具类下载配置

    1)GitHub上搜索通过搜索uiautomator来找到sumio/uiautomator-unicode-input-helper这个输入工具并下载
    2)点击eclipes左上角file–import–android/existing android code into workspase–next
    3)在新弹出的窗口导入下载好文件的路径(是解压后的文件)手动勾选copy projects into workspace然后点击finish
    4)导入完成后应该有一个name=Utf7Ime的project,右键点击工程–run as –android application,即可将输入法push到手机中
    5)手机系统设置–语言和输入法–设置UTF7为默认输入法
    6)在”gituiautomator-unicode-input-helper-masterUiAutomatorInputSamplesrc”路径下(代表你下载时候的存储位置)将两个文件夹(com/jp)copy到eclipes的用例工程的src下面,正常情况src下面会多出来三个包

    3.测试代码
    //输入中文
    public void testDemo1() throws UiObjectNotFoundException{
        //获取新建联系人的联系人姓名输入框
        UiObject edit=new UiObject(new UiSelector().className(EditText.class.getName()));
        edit.setText(Utf7ImeHelper.e("测试输入"));
    }

    三、获取应用信息

    • 实例:
    1.新建辅助apk(移步本文一、1.2.步骤)
    2.在辅助apk中创建广播类,代码如下:
    //Import文件
    import java.io.BufferedWriter;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStreamWriter;
    import java.util.List;
    
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    import android.content.pm.PackageInfo;
    import android.content.pm.PackageManager;
    import android.content.pm.PackageManager.NameNotFoundException;
    import android.content.pm.ResolveInfo;
    import android.os.Bundle;
    //广播接收器代码
    public class AppInfo extends BroadcastReceiver{
        public void onReceive(Context arg0, Intent arg1) {
            //使用bundle把我们要传的信息提取出来
            Bundle bundle=arg1.getExtras();
            //定义参数包名和文件名(pn,fn)
            String packageName=bundle.getString("pn");
            String fileName=bundle.getString("fn");
            //使用包管理来获取信息
            PackageManager pm=arg0.getPackageManager();
            try {
                PackageInfo manifext=pm.getPackageInfo(packageName, 0);
                //获取版本号
                String versionName=manifext.versionName;
                //获取应用的名子
                String apkName=pm.getApplicationLabel(pm.getApplicationInfo(packageName,0)).toString();
                //将信息写入文件
                writeFile("/mnt/sdcard", fileName, "versionName:"+versionName);
                writeFile("/mnt/sdcard", fileName, "apkName:"+apkName);
                //获取主activity查询条件
                Intent mainIntent=new Intent(Intent.ACTION_MAIN);
                mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
                mainIntent.setPackage(packageName);
                //通过上面的查询条件获取查询列表
                List<ResolveInfo> resolveInfos=pm.queryIntentActivities(mainIntent, PackageManager.MATCH_DEFAULT_ONLY);
                //列表判断
                for(ResolveInfo r:resolveInfos){
                    String activityName=r.activityInfo.name;
                    if(activityName.contains(packageName)){
                        //写入操作
                        writeFile("/mnt/sdcard", fileName, "activityName:"+activityName);
                    }
                }
            } catch (NameNotFoundException e) {
                e.printStackTrace();
            }
        }
        //写入文件的方法
        public void writeFile(String path,String fileName,String text){
            File file=new File(path+File.separator+fileName);
            try {
                //如果他不存在就创建一个
                if(!file.exists()){
                    file.createNewFile();   
                }
                //文件输出流
                FileOutputStream out=new FileOutputStream(file,true);
                OutputStreamWriter ow=new OutputStreamWriter(out);
                BufferedWriter bw=new BufferedWriter(ow);
    
                bw.append(text);
                bw.newLine();
                bw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    3.添加权限”android.permission.WRITE_EXTERNAL_STORAGE”(SD卡写入文件的权限),添加方法参考本文一、4步骤
    4.修改AndroidManiFest.xml文件注册广播接收器,在标签后面填入代码
    <receiver android:name=".AppInfo">//广播类名
        <intent-filter >
            <action android:name="jian.info.action"/>//自定义动作名
        </intent-filter>
    </receiver>
    5.右键点辅助APK工程–run as–android application,将apk安装到手机上
    6. 打开命令行,输入”adb shell am broadcast -a [自定义的name] -e pn [包名] -e fn [自定义文件名]”查看是否注册成功,按照上述代码,该命令的正确表现形式应该是”adb shell am broadcast -a jian.info.action -e pn com.android.clock -e fn apkInfo.txt”正常情况下SD卡下应该会有一个apkInfo.txt的文件
    7.编写测试用例,代码如下:
    //测试用例
    public void tesrDemo2(){
        //设置包名
        String packageName="com.android.deskclock";
        //获取
        String version=getApkInfo("versionName", packageName);
        String apkName=getApkInfo("vapkName", packageName);
        String activityName=getApkInfo("activityName", packageName);
        //输出
        System.out.println("version:"+version);
        System.out.println("apkName:"+apkName);
        System.out.println("activityName:"+activityName);
        //启动应用
        launchApp(packageName, activityName);
    }
    //启动应用的方法
    public void launchApp(String packageName,String activityName){
        String command="am start -W -n "+packageName+"/"+activityName;
        try {
            Runtime.getRuntime().exec(command);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    //写一个读文件的方法
    public String getApkInfo(String key,String packageName){
        //文件路径
        File file=new File("/mnt/sdcard/apkTestInfo.txt");
        //看文件是否存在,如果已存在就删除
        if(file.exists()){
            file.delete();
        }
        //定义命令
        String cmd="am broadcast -a jian.info.action"+" -e pn"+packageName+"-e fn apkTestInfo.txt";
        try {
            //当文件不存在的时候才执行cmd命令
            while(!file.exists()){
            Runtime.getRuntime().exec(cmd);
            sleep(5000);
            }
            FileInputStream in=new FileInputStream(file);
            InputStreamReader re=new InputStreamReader(in);
            BufferedReader reader=new BufferedReader(re);
            //逐行读取
            String line="";
            while((line=reader.readLine())!=null){
                if((line.contains(key))){
                    String[] s=line.split(":");
                    return s[1];
                }
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return "未获取到信息";
    }
  • 相关阅读:
    webStrom 注释模板添加
    匹配正则 url 端口 域名
    监测数据类型封装方法
    base64图片展示(后端给base64数据,前端展示图片)
    倒计时
    机密16位
    mvc与mvvm的区别
    flex表格的使用
    flex中tab页面的实现
    flex中下拉框的实现
  • 原文地址:https://www.cnblogs.com/JianXu/p/5225300.html
Copyright © 2020-2023  润新知