1. 程式人生 > >android UiAutomator生成報告類基本方法封裝

android UiAutomator生成報告類基本方法封裝

本人在使用android UiAutomator做測試的時候,用的是除錯方法生成的測試報告,因為執行環境實在電腦上,所以基本的封裝方法和UiAlibrary區分開了,主要是執行除錯命令和建立測試報告文件的方法比較多,關於檔案操作和javaIO流也不少,寫了不少註釋,分享出來,供大家參考。

package source;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Common {
	public static final String LINE = "\r\n";
	public static final String TAB = "\t";
	public static final String salt = "oY*
[email protected]
"; public static final String MX3DEVICESID = "353ACJJA4L8A"; public static final String NEXUS5DEVICESID = "06dbd10c0ae4e3af"; public static Common useOften = new Common(); public static Common getInstance() { return useOften; } public int getMark() { return (int) System.currentTimeMillis() / 1000; } public void outputBegin() {//輸出開始 System.out.println(getNow()+"..-. ...- 開始!"); } public void outputNow() {//輸出當前時間 System.out.println(getNow()); } public void outputOver() {//輸出結束 System.out.println(getNow()+"..-. ...- 結束!"); } public void output(String text) {//明顯輸出 System.out.println(text); } public void output(String ...text) {//方法過載 for (int i = 0; i < text.length; i++) { System.out.println("第"+ (i+1) + "個:"+ text[i]); } } public void output(double num) {//明顯輸出 System.out.println(num); } public void output(double ...num) {//方法過載 for (int i = 0; i < num.length; i++) { System.out.println("第"+ (i+1) + "個:"+ num[i]); } } public void output(int num) {//方法過載 System.out.println(num); } public void output(int ...num) {//方法過載 for (int i = 0; i < num.length; i++) { System.out.println("第"+ (i+1) + "個:"+ num[i]); } } public void outputError(Exception e) { output("暫未實現日誌記錄!"); e.printStackTrace(); } //輸出時間差 public void outputTimeDiffer(Date start, Date end) { long time = end.getTime() - start.getTime(); double differ = (double)time/1000; output("總計用時"+differ+"秒!"); } //匹配簡訊驗證碼 public String findCode(String message) { Pattern r = Pattern.compile("[0-9]{6}"); Matcher m = r.matcher(message); if (m.find()) { output("匹配成功"); for(int i=0;i<=m.groupCount();i++){ System.out.println(m.group(i)); } } return m.group(0); } //獲取記憶體資訊 public int getMemInfo(String info) { int result = 0; Pattern r = Pattern.compile(" [0-9]+ "); Matcher m = r.matcher(info); if (m.find()) { System.out.println(m.group()); result = changeStringToInt(m.group().trim()); } return result; } //獲取cpu執行資訊 public double getCpuInfo(String info) { String percent = info.substring(0, info.indexOf("%")); double result = changeStringToDouble(percent.trim()); return result; } //把string型別轉化為int public int changeStringToInt (String text) { // return Integer.parseInt(text); return Integer.valueOf(text); } //把string型別轉化為double public Double changeStringToDouble (String text) { // return Integer.parseInt(text); return Double.valueOf(text); } //執行cmd命令 public void execCmd(String cmd) { try { Process p = Runtime.getRuntime().exec(cmd);//通過runtime類執行cmd命令 // 正確輸出流 InputStream input = p.getInputStream();//建立並例項化輸入位元組流 BufferedReader reader = new BufferedReader(new InputStreamReader(input));//先通過inputstreamreader進行流轉化,在例項化bufferedreader,接收內容 String line = ""; while ((line = reader.readLine()) != null) {//迴圈讀取 System.out.println(line);//輸出 saveToFile(line, "runlog.log", false);//儲存,false表示不覆蓋 } reader.close();//此處reader依賴於input,應先關閉 input.close(); // 錯誤輸出流 InputStream errorInput = p.getErrorStream();//建立並例項化輸入位元組流 BufferedReader errorReader = new BufferedReader(new InputStreamReader(errorInput));//先通過inputstreamreader進行流轉化,在例項化bufferedreader,接收內容 String eline = ""; while ((eline = errorReader.readLine()) != null) {//迴圈讀取 System.out.println(eline);//輸出 saveToFile(eline, "runlog.log", false);//儲存,false表示不覆蓋 } errorReader.close();//此處有依賴關係,先關閉errorReader errorInput.close(); } catch (IOException e) { output("執行" + cmd + "失敗!"); e.printStackTrace(); } } public String[] execCmdAndReturnResult(String jarName,String testClass, String testName, int orderno) { int status = 0;//此引數用於提取執行code String runCmd = "adb shell uiautomator runtest ";//除錯命令的前半部分 String testCmd = jarName + ".jar " + "--nohup -c " + testClass + "#" + testName;//除錯命令的後半部分 System.out.println("----runTest: " + runCmd + testCmd);//輸出除錯命令 String runresult = "";//執行結果 String runinfo = "";//執行資訊 String errorlineinliabrary = "";//在library類的錯誤行 String errorlineinspecial = "";//在special類的錯誤行 String errorlineincase = "";//在case類的錯誤行 Date time1 = new Date();//開始時間 SimpleDateFormat now = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//設定時間格式 String starttime = now.format(time1);//轉換時間格式 String cmd = runCmd + testCmd;//拼接除錯命令 System.out.println("----execCmd: " + cmd);//輸出除錯命令 try { Process p = Runtime.getRuntime().exec("cmd /c " + cmd);//藉助runtime類執行除錯命令 // 正確輸出流 InputStream input = p.getInputStream();//正確輸出流,新建輸入流 BufferedReader reader = new BufferedReader(new InputStreamReader(input));//將位元組輸入流轉化為reader字元輸入流,並用bufferedreader接收資料 String line = "";//用來接收輸入流字元流的每一行 while ((line = reader.readLine()) != null) {//每次讀取一行賦值給line System.out.println(line);//輸出此行 saveToFile(line, "reportlog.log", false);//儲存此行到log裡面 if (line.startsWith("INSTRUMENTATION_STATUS_CODE:")) {//獲取執行報告的code碼 status ++;//此處因為每一個報告都有不只一個code,我們只要最後一個 if (status == 2) {//當status=2時,就是我們要的code System.out.println(getCode(line));//輸出此行的code if (getCode(line).equalsIgnoreCase("-1")) {//如果-1,則執行錯誤 runresult = "執行錯誤"; } else if (getCode(line).equalsIgnoreCase("-2")) {//如果-2則是斷言錯誤 runresult = "斷言錯誤"; } else { runresult = "執行成功";//此處就不判斷其他情況了,直接表示執行成功 } } } if (line.startsWith("INSTRUMENTATION_STATUS: stack=")) {//獲取錯誤和異常 runinfo = line.substring(30, line.length());//擷取我們需要的錯誤和異常 } if (line.startsWith(" at student.Special.")) {//獲取錯誤在special類發生的行 errorlineinspecial = line.substring(line.indexOf(".")+1, line.length());//擷取錯誤發生行 } if (line.startsWith(" at student.Case.")) {//獲取錯誤在case類發生的行 errorlineincase = line.substring(line.indexOf(".")+1, line.length());//擷取錯誤發生行 } if (line.startsWith(" at student.Library.")) {//獲取錯誤在library類發生的行 errorlineinliabrary = line.substring(line.indexOf(".")+1, line.length());//擷取錯誤發生行 } } reader.close();//此處有依賴關係,先關閉reader input.close();//關閉位元組輸入流 // 錯誤輸出流 InputStream errorInput = p.getErrorStream();//獲取錯誤流,新建輸出流 BufferedReader errorReader = new BufferedReader(new InputStreamReader(errorInput));////將位元組輸入流轉化為reader字元輸入流,並用bufferedreader接收資料 String eline = "";////用來接收輸入流字元流的每一行 while ((eline = errorReader.readLine()) != null) {//每次讀取一行賦值給line System.out.println(eline);//輸出此行 saveToFile(line, "runlog.log", false);//儲存此行到log裡面 } errorReader.close();//此處有依賴關係,先關閉errorReader errorInput.close();//關閉輸入位元組流 } catch (IOException e) { e.printStackTrace();//丟擲異常 } Date time = new Date();//獲取結束時間 String endtime = now.format(time);//轉化時間格式 String[] result = new String[9];//新建陣列存放執行資訊 result[0] = (orderno + 1) + "";//表示執行的用例的順序 result[1] = testName;//用例名 result[2] = runresult;//執行結果 result[3] = runinfo;//執行資訊 result[4] = errorlineinliabrary;//在library類的錯誤行 result[5] = errorlineinspecial;//在special類的錯誤行 result[6] = errorlineincase;//在case類的錯誤行 result[7] = starttime;//開始時間 result[8] = endtime;//結束時間 return result;//返回執行資訊 } //此方法僅用於執行已完成的方法,且指定裝置為nexus public void runTest(String jarName, String testClass, String testName) throws Exception { setMobileInputMethodToUtf(); String runCmd = "adb -s " + NEXUS5DEVICESID + " shell uiautomator runtest ";//除錯命令的前半部分 String testCmd = jarName + ".jar " + "--nohup -c " + testClass + "#" + testName;//除錯命令的後半部分 // System.out.println("----runTest: " + runCmd + testCmd);//輸出除錯命令 String cmd = runCmd + testCmd;//拼接除錯命令 System.out.println("----execCmd: " + cmd);//輸出除錯命令 try { Process p = Runtime.getRuntime().exec("cmd /c " + cmd);//藉助runtime類執行除錯命令 // 正確輸出流 InputStream input = p.getInputStream();//正確輸出流,新建輸入流 BufferedReader reader = new BufferedReader(new InputStreamReader(input));//將位元組輸入流轉化為reader字元輸入流,並用bufferedreader接收資料 String line = "";//用來接收輸入流字元流的每一行 while ((line = reader.readLine()) != null) {//每次讀取一行賦值給line System.out.println(line);//輸出此行 saveToFile(line, "runlog.log", false);//儲存此行到log裡面 } reader.close();//此處有依賴關係,先關閉reader input.close();//關閉位元組輸入流 // 錯誤輸出流 InputStream errorInput = p.getErrorStream();//獲取錯誤流,新建輸出流 BufferedReader errorReader = new BufferedReader(new InputStreamReader(errorInput));////將位元組輸入流轉化為reader字元輸入流,並用bufferedreader接收資料 String eline = "";////用來接收輸入流字元流的每一行 while ((eline = errorReader.readLine()) != null) {//每次讀取一行賦值給line System.out.println(eline);//輸出此行 saveToFile(line, "runlog.log", false);//儲存此行到log裡面 } errorReader.close();//此處有依賴關係,先關閉errorReader errorInput.close();//關閉輸入位元組流 } catch (IOException e) { e.printStackTrace();//丟擲異常 throw new Exception("執行cmd命令出錯!"); } setMobileInputMethodToQQ(); } //儲存到log檔案中 public void saveToFile(String text, String path, boolean isClose) throws IOException { File file = new File(path); BufferedWriter bf = null; FileOutputStream outputStream = new FileOutputStream(file, true); OutputStreamWriter outWriter = new OutputStreamWriter(outputStream); bf = new BufferedWriter(outWriter); bf.append(text); bf.newLine(); bf.flush(); if (isClose) { bf.close(); } outWriter.close();//此處有依賴關係,先關閉outWriter outputStream.close(); } //覆蓋寫入檔案 public void writerText(String path, String content) { File dirFile = new File(path); if (!dirFile.exists()) {//如果不存在,新建 dirFile.mkdir(); } try { //這裡加入true 可以不覆蓋原有TXT檔案內容,續寫 BufferedWriter bw1 = new BufferedWriter(new FileWriter(path));//通過檔案輸出流來用bufferedwrite接收寫入 bw1.write(content);//將內容寫到檔案中 bw1.flush();//強制輸出緩衝區內容 bw1.close();//關閉流 } catch (IOException e) { e.printStackTrace(); } } //修改nexus手機輸入法為utf7 public void setMobileInputMethodToUtf() { execCmd("adb -s 06dbd10c0ae4e3af shell settings put secure default_input_method jp.jun_nama.test.utf7ime/.Utf7ImeService"); } //設定nexus為QQ輸入法 public void setMobileInputMethodToQQ() { execCmd("adb -s 06dbd10c0ae4e3af shell settings put secure default_input_method com.tencent.qqpinyin/.QQPYInputMethodService"); } //獲取測試用例名 public String getTest(String text) { return text.substring(29, text.length()); } //獲取執行狀態碼 public String getCode(String text) { return text.substring(29, text.length()); } //獲取隨機數 public int getRandomInt(int num) { return new Random().nextInt(num); } //複製檔案 public void copyFile(String oldPath, String newPath) { System.out.println("原始檔路徑:" + oldPath); System.out.println("目標檔案路徑:" + newPath); try { int bytesum = 0;//這個用來統計需要寫入byte陣列的長度 int byteread = 0;//這個用來接收read()方法的返回值 File oldfile = new File(oldPath); if (oldfile.exists()) { // 檔案存在時 InputStream inStream = new FileInputStream(oldPath);//讀入原檔案,例項化輸入流 FileOutputStream fs = new FileOutputStream(newPath);//例項化輸出流 byte[] buffer = new byte[10000]; while ((byteread = inStream.read(buffer)) != -1) {//如何讀取到檔案末尾 bytesum += byteread;//位元組數 檔案大小 System.out.println(bytesum); fs.write(buffer, 0, byteread);//此方法第一個引數是byte陣列,第二次引數是開始位置,第三個引數是長度 } fs.flush();//強制快取輸出 fs.close();//關閉輸出流 inStream.close();//關閉輸入流 } } catch (Exception e) { System.out.println("複製單個檔案操作出錯"); e.printStackTrace(); } // File oldfile2 = new File(oldPath); // oldfile2.delete(); } public String getDevicesId(String devices) { if (devices.equals("MX3")) { return MX3DEVICESID; } else if (devices.equals("nexus5")) { return NEXUS5DEVICESID; } else { return NEXUS5DEVICESID; } } //新建測試報告目錄 public String creatNewFile(String time) { File file = new File("C:\\Users\\fankaiqiang\\Desktop\\888\\"+"testreport"+time); if (!file.exists()) { file.mkdir(); } return file.toString(); } //獲取當前工作路徑 public String getWorkSpase() { File directory = new File(""); String abPath = directory.getAbsolutePath(); return abPath; } //執行cmd命令,控制檯資訊編碼方式GBK public void execCmdByGBK(String cmd) throws IOException { System.out.println(cmd); try { Process p = Runtime.getRuntime().exec("cmd /c " + cmd); InputStreamReader inputStreamReader = new InputStreamReader(p.getInputStream(), Charset.forName("GBK")); BufferedReader br = new BufferedReader(inputStreamReader); String line=null; while((line = br.readLine()) != null){ System.out.println(line); } br.close();//此處有依賴,先關閉br inputStreamReader.close(); } catch (IOException e) { output("執行" + cmd + "失敗!"); e.printStackTrace(); } } //設定nexus亮度250 public void setScreenLightTo250() { execCmd("adb -s "+NEXUS5DEVICESID+" shell settings put system screen_brightness 250"); } //設定nexus螢幕亮度150 public void setScreenLightTo150() { execCmd("adb -s "+NEXUS5DEVICESID+" shell settings put system screen_brightness 150"); } //刪除字元 public String deleteCharFromString(String delChar, String text) { return text.replace(delChar, ""); } public String getNow() {//獲取當前時間 Date time = new Date(); SimpleDateFormat now = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss"); String c = now.format(time); return c; } public void deleteScreenShot() {//刪除截圖資料夾 File file = new File("/mnt/sdcard/123/"); if (file.exists()) {//如果file存在 File[] files = file.listFiles();//獲取資料夾下檔案列表 for (int i = 0; i < files.length; i++) {//遍歷刪除 files[i].delete(); } file.delete();//最後刪除資料夾,如果不存在直接刪除資料夾 } else { output("資料夾不存在!"); } } //使用md5加密資料 public String encodeByMd5(String text) throws UnsupportedEncodingException, NoSuchAlgorithmException { byte[] date = text.getBytes("utf-8"); MessageDigest message = MessageDigest.getInstance("md5"); message.update(date); byte[] result = message.digest(); StringBuffer stringBuffer = new StringBuffer(); // for (int i = 0; i < result.length; i++) { // stringBuffer.append(Integer.toHexString(0xff & result[i]));//此處使用0xff為了防止負數 // } // library.output(stringBuffer.toString()); for (int offset = 0; offset < result.length; offset++) { int i = result[offset]; if (i < 0)//如果負數 i += 256;//變成正數,0xff & i 也可以 if (i < 16)//如果小於16,則加上0小於16,轉換之後就是一位缺少一位故要加0 stringBuffer.append("0"); stringBuffer.append(Integer.toHexString(i)); } return stringBuffer.toString(); } //輸出時間差 public double outputTimeDiffer(Date start, Date end, String message) { long time = end.getTime() - start.getTime(); double differ = (double)time/1000; output(message + "----總計用時"+differ+"秒!"); return differ; } //獲取當前方法 public String getCurrentMethodName() { return Thread.currentThread().getStackTrace()[1].getMethodName(); } //獲取當前類 public String getCurrentClass() { return Thread.currentThread().getStackTrace()[1].getClassName(); } //獲取當前時間,返回date型別 public Date getDate() { return new Date(); } public String getToken(int uid) { String token = null; try { token = encodeByMd5(uid + salt); } catch (UnsupportedEncodingException | NoSuchAlgorithmException e) { output("加密失敗!"); e.printStackTrace(); } return token; } }

末尾宣傳一下UiAutomator交流群,起於UiAutomator,不止於UiAutomator。


相關推薦

android UiAutomator生成報告基本方法封裝

本人在使用android UiAutomator做測試的時候,用的是除錯方法生成的測試報告,因為執行環境實在電腦上,所以基本的封裝方法和UiAlibrary區分開了,主要是執行除錯命令和建立測試報告文件的方法比較多,關於檔案操作和javaIO流也不少,寫了不少註釋,分享出來

eclipse反向生成實體方法

Eclipse中使用Hibernate-tools反向生成hibernate實體類 一.準備工作 1.Eclipse版本:Kepler Service Release 1。 二.安裝hibernate-tools 1.點選help—>install new  sof

Java併發21:Lock系列-ReadWriteLock介面和ReentrantReadWriteLock基本方法學習例項

本章主要學習讀寫鎖。 關於讀寫鎖,在《 Java併發18》中已經學習過: synchronized關鍵字只提供了一種鎖,即互斥鎖。 java.util.concurretn.locks包不僅通過Lock介面提供了與前者類似的互斥鎖,而且還通過Rea

java bean基本方法重寫

類基本方法(toString、hashCode、equals、compareTo)重寫 使用jar包為 apache的commons集lang包 1. toString() 實現一

android UiAutomator獲取當前頁面某控制元件個數的方法

本人在學習UiAutomator的時候,發現一個問題,就是我需要知道當前班級作業的個數,本來想用getchildCount(),發現原來是按行的,一行不一定有多少個小題,後來就想了一個辦法,selenium2java,裡面有一個findelements()的方法,借鑑了這個

android UiAutomator基本api的二次封裝

本人在使用UiAutomator做測試的時候,封裝了很多方法,由於之前的文章並沒有分享這些封裝方法,導致閱讀不暢。本來打算再把影象識別和輔助類寫完在分享,鑑於已經離職,UI這塊很長時間不太會更新程式碼了,就把所有的封裝方法都分享出來了。裡面有些過時的,暫時無用的大家可以忽略

使用Data Binding Android Studio不能正常生成相關/方法的解決辦法

本系列目錄 有時候新建佈局檔案時或者定義佈局中的變數時,不能即時生成相關Binding類或方法(其實是不能正確索引),也許是IDE支援的一些BUG,不過Android Studio對Data Binding的支援問題也僅限於這些,並且可以比較簡單地解

Android經常使用工具封裝---SharedPreferencesUtil

保存數據 n) ng- -a 操作 ext.get 名稱 simple tint SharedPreferences經常使用於保存一些簡單的數據,如記錄用戶操作的配置等,使用簡單。 public class SharedPreferencesUtil { //存

【java】String基本方法

lastindex bool bsp sta substr 方法 相等 當前 start Java的String類基本方法 一、構造函數 函數 返回值 作用 String(byte[] bytes) String 通過byte數組構造字符串對象 String(

Java中的基本數據型及其封裝

實例化 too shadow color ant 基本類 實用 anti 泛型 Java中的數據類型有兩種,基本數據類型和引用數據類型,引用數據類型的創建是需要去new一個對象,該對象的內存分配在堆區,同時棧區會保存一個指向該對象的引用,但是對於一些簡單數據的創建,

Android Studio安裝部署系列】二十二、Android studio自動生成set、get方法

setter 自動生成 全選 style 原創文章 back .com 安裝部署 dash 版權聲明:本文為博主原創文章,未經博主允許不得轉載。 操作步驟 將光標放置我們所要生成get,set方法的實體類空白處——然後右鍵—&mdas

正確生成浮點型的方法,解決sqlachemy Float浮點型的坑,生成float型時,長度和精度均為0,導致查詢不到結果!

依然 tab 圖片 control 選擇 分享 ice mod ble 問題描述 在使用flask_sqlachemy時,給price字段選擇了Float類型,數據庫用的mysql,生成數據庫表後,發現 from sqlalchemy import Float

Java面向對象-- String 常用方法基本使用

for str news http clas substr 實例 div print 首先來學習基本使用Jdk api chm文檔: 點擊 左上角-顯示: 1, char chartAt(int index) 返回指定索引處的char值 這裏的index 是從0

Android Studio 外掛 GsonFormat 自動生成實體

Android  Studio 中自帶 GsonFormat 外掛,可以根據你的Json 串,自動生成相應的實體類。非常方便。介紹下使用教程: 第一步 : File --->Setting------>Plugins,然後搜尋GsonFormat。

JS的陣列,string的定義及基本方法

函式: 函式在呼叫的時候,會形成一個私有作用域,內部的變數不會被外面訪問,這種保護機制叫閉包。這就意味著函式呼叫完畢,這個函式形成的棧記憶體會被銷燬。 function fn(){ var a=12; a++; console.log(a) } fn()----13 fn()----13 fn()---

Java面向物件-- String 常用方法基本使用

首先來學習基本使用Jdk api chm文件: 點選 左上角-顯示:     1, char chartAt(int index) 返回指定索引處的char值 這裡的index 是從0開始的; package com.xuyigang1234.chp02.strin

php生成縮圖方法封裝

------------------------------------------------- 引數: $filename : 要裁剪的圖片路徑 $destination : 要生成的圖片資料夾和路徑 $dst_w : 要把圖片裁剪到多寬 $dst_h : 要把圖片裁剪到多高

利用基本資料封裝(如:Integer,Float)等實現資料型別轉換

/** * 利用基本資料封裝類進行資料型別轉換 * @author dyh * */ public class TypeConversion { public static void main(String[] args) { //字串轉換為各常用基本資料型別 String str

.net core 中簡單封裝Dapper.Extensions 並使用sqlsuger自動生成實體

引言 由公司需要使用dapper  同時支援多資料庫 又需要支援實體類 又需要支援sql 還需要支援事務 所以採用了 dapper + dapperExtensions  並配套 生成實體類小工具的方式     環境準備 dapper環境 nuget中

9-Unittest+HTMLTestRunner不能生成報告解決方法

  1、問題現象     在使用HTMLTestRunner生成測試報告時,出現程式執行不報錯,但不能生成報告的情況。     剛開始找了很久沒發現問題,後來加上列印資訊,發現根本沒執行生成報告這部分程式碼。最後網上找到原因:pycharm 在執行測試用