標籤:des android io os ar 使用 java for sp
接到一個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即可了,沒興趣花時間去為了這麼點功能啃骨頭。
同學們看著玩吧。
手把手教你_android自己主動化實踐方案選型