Android UiAutomator 快速调试

Posted zeotoone

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android UiAutomator 快速调试相关的知识,希望对你有一定的参考价值。

背景:在Eclipse中不能直接运行Uiautomator工程,所以每次编写一份用例都要进行手动输入命令创建build文件、ant编译文件、push文件与运行测试这四步。调试起来不仅繁琐还浪费时间。网上找到一份快速调试的代码UiAutomatorHelper,可将这几步进行简化很方便。

步骤:将UiAutomatorHelper.java放到工程目录下(与测试脚本同步目录),在测试脚本中写个main方法。然后Run as ->java application即可

 1 package com.change.display;
 2 
 3 
 4 import java.io.IOException;
 5 
 6 import android.os.RemoteException;
 7 
 8 import com.android.uiautomator.core.UiDevice;
 9 import com.android.uiautomator.core.UiObject;
10 import com.android.uiautomator.core.UiObjectNotFoundException;
11 import com.android.uiautomator.core.UiSelector;
12 import com.android.uiautomator.testrunner.UiAutomatorTestCase;
13 
14 public class Display extends UiAutomatorTestCase{
15     public static void main(String [] arg ){
16         String jarName="ChangeFont";
17         String testClass="com.change.display.Display";
18         String testName="test1";
19         String androidId="1";
20         new UiAutomatorHelper(jarName, testClass, testName, androidId);        
21     }
22     public void test1 () throws UiObjectNotFoundException, RemoteException, IOException{
23         //Device wake up
24         UiDevice.getInstance().wakeUp();
25         //sleep 3s
26         sleep(3000);
27         //Open the settings
28         Runtime.getRuntime().exec("am start -n com.android.settings/.Settings");
29         //Click on display
30         try{
31             UiObject display = new UiObject(new UiSelector().text("显示"));
32             display.click();
33             sleep(3000);
34         }catch(Exception e){
35             e.printStackTrace();
36         }
37         //Select font
38         UiObject fs = new UiObject(new UiSelector().text("字体大小"));
39         fs.clickAndWaitForNewWindow();
40         //Change font
41         UiObject size = new UiObject(new UiSelector().text("超大"));
42         size.click();
43         //Screen shot
44         sleep(3000);
45         Runtime.getRuntime().exec("screencap -p /sdcard/test.png");    
46         //Enter Home interface
47         sleep(3000);
48         getUiDevice().pressHome();                     
49     }
50 }

 

顺带附上UiAutomatorHelper.java代码

技术分享
  1 package com.change.display;
  2 
  3 import java.io.BufferedReader;
  4 import java.io.BufferedWriter;
  5 import java.io.File;
  6 import java.io.FileInputStream;
  7 import java.io.FileNotFoundException;
  8 import java.io.FileOutputStream;
  9 import java.io.FileWriter;
 10 import java.io.IOException;
 11 import java.io.InputStream;
 12 import java.io.InputStreamReader;
 13 import java.io.OutputStreamWriter;
 14 
 15 public class UiAutomatorHelper {
 16 
 17     // 以下参数需要配置,用例集id,用例id,安卓id
 18     private static String android_id = "3";
 19     private static String jar_name = "";
 20     private static String test_class = "";
 21     private static String test_name = "";
 22 
 23     // 工作空间不需要配置,自动获取工作空间目录
 24     private static String workspace_path;
 25 
 26     public static void main(String[] args) {
 27         
 28     }
 29     public UiAutomatorHelper() {
 30         workspace_path = getWorkSpase();
 31         System.out.println("---工作空间:\t\n" + getWorkSpase());
 32     }
 33 
 34     /**
 35      * 需求:UI工程调试构造器,输入jar包名,包名,类名,用例名
 36      * @param jarName
 37      * @param testClass
 38      * @param testName
 39      * @param androidId
 40      */
 41     public UiAutomatorHelper(String jarName, String testClass, String testName,
 42             String androidId) {
 43         System.out.println("-----------start--uiautomator--debug-------------");
 44         workspace_path = getWorkSpase();
 45         System.out.println("----工作空间:\t\n" + getWorkSpase());
 46 
 47         jar_name = jarName;
 48         test_class = testClass;
 49         test_name = testName;
 50         android_id = androidId;
 51         runUiautomator();
 52         System.out.println("*******************");
 53         System.out.println("---FINISH DEBUG----");
 54         System.out.println("*******************");
 55     }
 56     /**
 57      * 需求:build 和 复制jar到指定目录
 58      * @param jarName
 59      * @param testClass
 60      * @param testName
 61      * @param androidId
 62      * @param isRun
 63      */
 64     public UiAutomatorHelper(String jarName, String testClass, String testName,
 65             String androidId,String ctsTestCasePath){
 66         System.out.println("-----------start--uiautomator--debug-------------");
 67         workspace_path = getWorkSpase();
 68         System.out.println("----工作空间:\t\n" + getWorkSpase());
 69 
 70         jar_name = jarName;
 71         test_class = testClass;
 72         test_name = testName;
 73         android_id = androidId;
 74         buildUiautomator(ctsTestCasePath);
 75         
 76         System.out.println("*******************");
 77         System.out.println("---FINISH DEBUG----");
 78         System.out.println("*******************");
 79         
 80     }
 81     // 运行步骤
 82     private void runUiautomator() {
 83         creatBuildXml();
 84         modfileBuild();
 85         buildWithAnt();
 86         if (System.getProperty("os.name").equals("Linux")) {
 87             pushTestJar(workspace_path + "/bin/" + jar_name + ".jar");
 88         }else{
 89         pushTestJar(workspace_path + "\\bin\\" + jar_name + ".jar");
 90         }
 91         
 92         if (test_name.equals("")) {
 93             runTest(jar_name, test_class);
 94             return;
 95         }
 96         runTest(jar_name, test_class + "#" + test_name);
 97     }        
 98 
 99 
100     // 1--判断是否有build
101     public boolean isBuild() {
102         File buildFile = new File("build.xml");
103         if (buildFile.exists()) {
104             return true;
105         }
106         // 创建build.xml
107         execCmd("cmd /c android create uitest-project -n " + jar_name + " -t "
108                 + android_id + " -p " + workspace_path);
109         return false;
110     }
111 
112     // 创建build.xml
113     public void creatBuildXml() {
114         execCmd("cmd /c android create uitest-project -n " + jar_name + " -t "
115                 + android_id + " -p " + "\""+workspace_path+ "\"");
116     }
117 
118     // 2---修改build
119     public void modfileBuild() {
120         StringBuffer stringBuffer = new StringBuffer();
121         try {
122             File file = new File("build.xml");
123             if (file.isFile() && file.exists()) { // 判断文件是否存在
124                 InputStreamReader read = new InputStreamReader(
125                         new FileInputStream(file));
126                 BufferedReader bufferedReader = new BufferedReader(read);
127                 String lineTxt = null;
128                 while ((lineTxt = bufferedReader.readLine()) != null) {
129                     if (lineTxt.matches(".*help.*")) {
130                         lineTxt = lineTxt.replaceAll("help", "build");
131                         // System.out.println("修改后: " + lineTxt);
132                     }
133                     stringBuffer = stringBuffer.append(lineTxt + "\t\n");
134                 }
135                 read.close();
136             } else {
137                 System.out.println("找不到指定的文件");
138             }
139         } catch (Exception e) {
140             System.out.println("读取文件内容出错");
141             e.printStackTrace();
142         }
143 
144         System.out.println("-----------------------");
145 
146         // 修改后写回去
147         writerText("build.xml", new String(stringBuffer));
148         System.out.println("--------修改build完成---------");
149     }
150 
151     
152 
153     // 3---ant 执行build
154     public void buildWithAnt() {
155         if (System.getProperty("os.name").equals("Linux")) {
156             execCmd("ant");
157             return;
158         }
159         execCmd("cmd /c ant");
160     }
161 
162     // 4---push jar
163     public void pushTestJar(String localPath) {
164         localPath="\""+localPath+"\"";
165         System.out.println("----jar包路径: "+localPath);
166         String pushCmd = "adb push " + localPath + " /data/local/tmp/";
167         System.out.println("----" + pushCmd);
168         execCmd(pushCmd);
169     }
170 
171     // 运行测试
172     public void runTest(String jarName, String testName) {
173         String runCmd = "adb shell uiautomator runtest ";
174         String testCmd = jarName + ".jar " + "--nohup -c " + testName;
175         System.out.println("----runTest:  " + runCmd + testCmd);
176         execCmd(runCmd + testCmd);
177     }
178 
179     public String getWorkSpase() {
180         File directory = new File("");
181         String abPath = directory.getAbsolutePath();
182         return abPath;
183     }
184     
185     /**
186      * 需求:执行cmd命令,且输出信息到控制台
187      * @param cmd
188      */
189     public void execCmd(String cmd) {
190         System.out.println("----execCmd:  " + cmd);
191         try {
192             Process p = Runtime.getRuntime().exec(cmd);
193             //正确输出流
194             InputStream input = p.getInputStream();
195             BufferedReader reader = new BufferedReader(new InputStreamReader(
196                     input));
197             String line = "";
198             while ((line = reader.readLine()) != null) {
199                 System.out.println(line);
200                 saveToFile(line, "runlog.log", false);
201             }
202             //错误输出流
203             InputStream errorInput = p.getErrorStream();
204             BufferedReader errorReader = new BufferedReader(new InputStreamReader(
205                     errorInput));
206             String eline = "";
207             while ((eline = errorReader.readLine()) != null) {
208                 System.out.println(eline);
209                 saveToFile(eline, "runlog.log", false);
210             }       
211         } catch (IOException e) {
212             e.printStackTrace();
213         }
214     }
215     /**
216      * 需求:写如内容到指定的文件中
217      * 
218      * @param path
219      *            文件的路径
220      * @param content
221      *            写入文件的内容
222      */
223     public void writerText(String path, String content) {
224 
225         File dirFile = new File(path);
226 
227         if (!dirFile.exists()) {
228             dirFile.mkdir();
229         }
230 
231         try {
232             // new FileWriter(path + "t.txt", true) 这里加入true 可以不覆盖原有TXT文件内容 续写
233             BufferedWriter bw1 = new BufferedWriter(new FileWriter(path));
234             bw1.write(content);
235             bw1.flush();
236             bw1.close();
237         } catch (IOException e) {
238             e.printStackTrace();
239         }
240     }
241 
242     public void saveToFile(String text,String path,boolean isClose) {
243         File file=new File("runlog.log");       
244         BufferedWriter bf=null;
245         try {
246             FileOutputStream outputStream=new FileOutputStream(file,true);
247             OutputStreamWriter outWriter=new OutputStreamWriter(outputStream);
248             bf=new BufferedWriter(outWriter);
249             bf.append(text);
250             bf.newLine();
251             bf.flush();
252             
253             if(isClose){
254                 bf.close();
255             }
256         } catch (FileNotFoundException e1) {
257             e1.printStackTrace();
258         } catch (IOException e) {
259             e.printStackTrace();
260         }
261 
262         
263     }
264     /**
265      * 需求:编译和复制jar包指定文件
266      * @param newPath
267      */
268     private void buildUiautomator(String newPath) {
269         creatBuildXml();
270         modfileBuild();
271         buildWithAnt();
272         //复制文件到指定文件夹
273         copyFile(workspace_path + "\\bin\\" + jar_name + ".jar", newPath);
274         
275     }
276     /** 
277      * 复制单个文件 
278      * @param oldPath String 原文件路径 如:c:/fqf.txt 
279      * @param newPath String 复制后路径 如:f:/fqf.txt 
280      * @return boolean 
281      */ 
282    public void copyFile(String oldPath, String newPath) { 
283        System.out.println("源文件路径:"+oldPath);
284        System.out.println("目标文件路径:"+newPath);
285        try { 
286            int bytesum = 0; 
287            int byteread = 0; 
288            File oldfile = new File(oldPath); 
289            if (oldfile.exists()) { //文件存在时 
290                InputStream inStream = new FileInputStream(oldPath); //读入原文件 
291                FileOutputStream fs = new FileOutputStream(newPath); 
292                byte[] buffer = new byte[1444]; 
293                int length; 
294                while ( (byteread = inStream.read(buffer)) != -1) { 
295                    bytesum += byteread; //字节数 文件大小 
296                    System.out.println(bytesum); 
297                    fs.write(buffer, 0, byteread); 
298                } 
299                inStream.close(); 
300            } 
301        } 
302        catch (Exception e) { 
303            System.out.println("复制单个文件操作出错"); 
304            e.printStackTrace(); 
305 
306        } 
307 
308    } 
309 }
UiAutomatorHelper

 

以上是关于Android UiAutomator 快速调试的主要内容,如果未能解决你的问题,请参考以下文章

Uiautomator自动化测试编写和调试

Uiautomator自动化测试编写和调试

怎样在Android Studio中使用Uiautomator

android自动化测试-UiAutomator使用入门

使用uiautomator2实现对手机app的操作(windows)

appium + python 自动化调试手机时 UiAutomator exited unexpectedly with code 0, signal null