Google在sdk4.0以後提供了壹個自動化解決方案uiautomator:
優點:可以跨應用了;這可是親生的;
缺點:必須sdk4.0以上版本;要想實現的好,最好有開發配合;java項目編譯為jar後需要push到手機才能運行,也就是說必須打印日誌暴力調試。
Appium基於Android InstrumentationFramework和UIAutomator,也就是說這個工具是可以跨應用的。說遠了,好吧,為了更容易理解appium的使用
(2)uiautomator的使用方法:
應該有android-sdk吧,升級到4.0以上,進入目錄android-sdk\tools,會看到兩個文件:
traceview.bat 和 uiautomatorviewer.bat,這倆文件想起了monkeyrunner了吧,是的,traceview.bat就對應於hierarchyviewer.bat,用來查看程序的ui界面的,通常也是使用管理員權限啟動的。
好了,現在用eclipse創建壹個java project,是的,沒看錯,是java project不是android project,添加引用:
在project.properties中內容為:
# Project target.
target= android-16
這裏的android-16需要和之前的android.jar和uiautomator.jar位置相壹致。
(3)代碼參考:
package com.uia.example.my;
import org.apache..android.uiautomator.core.UiObject;
import com.android.uiautomator.core.UiObjectNotFoundException;
import com.android.uiautomator.core.UiScrollable;
import com.android.uiautomator.core. UiSelector ;
import com.android.uiautomator.testrunner.UiAutomatorTestCase;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class TAppWorkAssistV1 extends UiAutomatorTestCase {
public String sLog ;
public File fout = null ;
public FileOutputStream outStream = null ;
public void write2file(String filename,String sData)
{
String sLog= "" ;
// 初始化日誌文件
if (Environment. getExternalStorageState ().equals(Environment.MEDIA_MOUNTED )){
sLog = Environment. getExternalStorageDirectory().getAbsolutePath();
try {
fout = new File(sLog,filename);
outStream = new FileOutputStream( fout , true ); // 此處的 true 是append
sData=sData + "\n" ;
outStream .write(sData.getBytes());
outStream .flush();
outStream .close();
fout = null ;
}
catch (Exception e){
e.printStackTrace();
}
} else {
System. out .println( " 該手機沒有 SD 卡 " );
}
}
public void testDemo() throws UiObjectNotFoundException {
//1. 啟動 app
getUiDevice().pressHome();
UiObject allAppsButton = new UiObject( newUiSelector().description( "Apps" ));
allAppsButton.clickAndWaitForNewWindow();
UiObject appsTab = new UiObject( new UiSelector().text( "Apps" ));
appsTab.click();
UiScrollable appViews = new UiScrollable( newUiSelector().scrollable( true ));
UiObject settingsApp = appViews.getChildByText( newUiSelector().className(android.widget.TextView. class .getName()), "Efilm" );
settingsApp.clickAndWaitForNewWindow();
//2. 進入主界面
System. out .println( "into main view" );
System. out .println(getUiDevice().waitForWindowUpdate("com.eshore.efilm" , 60000));
System. out .println( "intoed main view" );
UiObject tv1 = new UiObject( new UiSelector().text( " 影院 " ));
tv1.click();
//3. 點擊影院
UiObject oyy= new UiObject( new UiSelector().description("cinema_row" ));
System. out .println( "wait yingyuan come out" );
oyy.waitForExists(60000);
System. out .println( "yingyuan come out" );
oyy.clickAndWaitForNewWindow();
System. out .println( "click yingyuan" );
//4. 場次
UiObject occ= new UiObject( new UiSelector().description("LinearLayout10" ));
System. out .println( "wait changci come out" );
oyy.waitForExists(60000);
System. out .println( "changci come out" );
occ.clickAndWaitForNewWindow();
System. out .println( "click changci" );
//5. 座位
UiObject oseat= new UiObject( new UiSelector().description("cinema_shows_list_item" ).index(0).childSelector( newUiSelector().description( "LinearLayout10" )));
System. out .println( "wait seat come out" );
oseat.waitForExists(5000);
int h=getUiDevice().getDisplayHeight();
int w=getUiDevice().getDisplayWidth();
System. out .println( "(h/2,w/2)=" +h/2+ "," +w/2);
getUiDevice().click(h/2,w/2);
//System.out.println("seat count:"+String.valueOf(oseat.getChildCount()));
//System.out.println("seat getText:"+ oseat.getText());
// 截座位圖
Process process;
try {
process = Runtime. getRuntime ().exec( "screencap /mnt/sdcard/EfilmFailSnapShot01.png" );
try {
process.waitFor();
} catch (InterruptedException e) { // TODO Auto-generated catch block
e.printStackTrace();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//takeScreenShots("EfilmSeatSnapShot");
}
}
(4)執行:
這個例子是隨便寫的,可能不夠嚴謹。大體就這麽個情況吧。下壹步就是編譯執行了,先插上手機usb接口,然後打開cmd,執行:
找到SDKID,也就是android create中的-t參數:
cd C:\ PROGRAM\android-sdk\tools
android list
找到t參數的值以後:
cd C:\ PROGRAM\android-sdk\tools
android create uitest-project -n TAppWorkAssistV1 -t 25 -p C:\android自動化\Tv2.0\TestSetting
cd C:\android自動化\Tv2.0\TestSetting
ant build
cd C:\android自動化\Tv2.0\TestSetting\bin
adb push TAppWorkAssistV1.jar /data/local/tmp/
adb shell uiautomator runtest TAppWorkAssistV1.jar -c com.uia.example.my. TAppWorkAssistV1
(5)需要註意的:
-n TAppWorkAssistV1:類名
-p: 項目所在目錄
Ant build 把這個類編譯成壹個jar包:TAppWorkAssistV1.jar
然後把jar包push到手機上,調用執行這個類就可以了
大致是這麽個步驟,不過有壹個非常重要的細節,就是如果需要更省心,就最好把界面元素,無論動態的還是布局文件中的,都加上content-description屬性,並保證唯壹性,根據:
UiSelector:description(String desc)
Set the search criteria to match thecontent-description property for a widget.
那就可以統壹只使用這壹個引用界面元素的方法就行了,就不用去想方設法利用其它的屬性來引用了。