本篇文章主要是用以介绍用uiautomator模拟monkey的点击事件运行机制来进行自动化的测试用例书写,为后期性能测试做基础。我们将写一个基础的case做试例。
首先我们要获取页面中可以点击的元素存在一个List中,供我们后面点击随机事件做准备,需要用到的是“By.clickable(true)”
List<UiObject2> allAppsButton = mDevice.findObjects(By.clickable(true));
之后我们需要做一个随机数,这个数我们就通过list的长度来定义,需要用到随机方法Random()
Random r=new Random();
int b=r.nextInt(allAppsButton.size());
最后我们直接进行点击就好了。
allAppsButton.get(b).click();
这样流程是通了,那我们发现先运行过程中还是有很多问题需要注意的:如果上一个操作导致程序到了后台或者异常退出怎么办?点击过程中点到了一些悬浮的按钮了怎么办?那下面我们进行一一的解决
二,判断程序是否在前台
判断是不是在前台我们首先要判断这个应用程序是否启动了,这里我们需要用到ActivityManager.RunningAppProcessInfo 获取 appProcesses List 再到这个List中 之后在通过 appProcesses.processName 来对比应用的PackageName 如果没有就证明应用没有启动,如果有启动那我们就需要通过之前匹配到的appProcesses 来对比现在程序用在后台的应用是不是同一个,我们需要用到appProcess.importance 对比 ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND 如果是的话那就是在后台了。
ActivityManager activityManager = (ActivityManager) context.getSystemService(ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
if (appProcess.processName.equals(mPackageName)) {
if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
return false;
}
else{
return true;
}
}
}
return false;
}
需要注意的是:安卓5.0以上不支持ActivityManager.getRunningAppProcesses方法 那么需要就需要另个方法了AndroidProcesses.getRunningAppProcesses()
List<AndroidAppProcess> processes = AndroidProcesses.getRunningAppProcesses();
for(AndroidAppProcess appProcess : processes){
if(appProcess.name.equals(mPackageName)){
System.out.println(appProcess.name);
if(appProcess.foreground){
return true;
}else{return false;}
}
}
return false;
三,排除掉非应用按钮
前面有获取到过页面中全部个点击的按钮,现在我们这里借用一下,在建立一个List用于存放排除好的按钮List<UiObject2> clickTrueBut = new ArrayList<>();
之后在遍历之前的按钮中的包名是不是测试的应用包名,之后再一个个的添加到clickTrueBut 中就得到一个新的确认可以点击List了
List<UiObject2> clickTrueBut = new ArrayList<>();
int length = allAppsButton.size();
for(int a=0;a<length;a++){
if(allAppsButton.get(a).getApplicationPackage().equals(mPackageName)){
clickTrueBut.add(allAppsButton.get(a));
}
}
四,总结(附代码)
通过以上的的工作,基本上一个简单的随机的case就可以完成啦,当然我们要写一个循环去进行不停的点击。以下是case代码:
public class AppTest {
private final String TAG=getClass().getName();
private String mPackageName="PackageName";
private Context context=getInstrumentation().getContext();
private Random r=new Random();
private int clickNumber =1000;//点击次数
UiDevice mDevice=UiDevice.getInstance(getInstrumentation());//获取设备用例
@Test
public void case1(){
try {
if(!mDevice.isScreenOn()){
mDevice.wakeUp();//唤醒屏幕
}
} catch (RemoteException e) {
e.printStackTrace();
}
if(!naviStatus(context)){
startAPP(mPackageName);
}
for (int a=1;a<clickNumber;a++){
pause(5);
randomclick();
}
}
private void startAPP(String sPackageName){
Intent myIntent = context.getPackageManager().getLaunchIntentForPackage(sPackageName); //通过Intent启动app
context.startActivity(myIntent);
}
private void randomclick(){
List<UiObject2> allAppsButton = mDevice.findObjects(By.clickable(true));
List<UiObject2> clickTrueBut = new ArrayList<>();
int length = allAppsButton.size();
for(int a=0;a<length;a++){
if(allAppsButton.get(a).getApplicationPackage().equals(mPackageName)){
clickTrueBut.add(allAppsButton.get(a));
}
}
clickTrueBut.get(b).click();
}
private boolean naviStatus(Context context) {
String androidVersion = Build.VERSION.RELEASE;
int sdkVersion = Build.VERSION.SDK_INT;
System.out.println("androidVersion:"+androidVersion+"sdkVersion:"+sdkVersion);
//安卓5.0以上不支持getRunningAppProcesses方法,使用第三方库的方法
if(sdkVersion > 19){
List<AndroidAppProcess> processes = AndroidProcesses.getRunningAppProcesses();
System.out.println("进程数量:"+processes.size());
for(AndroidAppProcess appProcess : processes){
if(appProcess.name.equals(mPackageName)){
System.out.println(appProcess.name);
if(appProcess.foreground) return true;
else{return false;}
}
}
System.out.println("未匹配到进程");
return false;
}else{
ActivityManager activityManager = (ActivityManager) context.getSystemService(ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
if (appProcess.processName.equals(mPackageName)) {
if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
//后台
return false;
}else{
//前台
return true;
}
}
}
//应用退出了
return false;
}
}
public void pause(int times){
try {
Thread.sleep(times*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}