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 }
以上是关于Android UiAutomator 快速调试的主要内容,如果未能解决你的问题,请参考以下文章
怎样在Android Studio中使用Uiautomator
使用uiautomator2实现对手机app的操作(windows)
appium + python 自动化调试手机时 UiAutomator exited unexpectedly with code 0, signal null