Uiatomator2 初步探索
BySelector
主要是用来搜索确定我们要操作的对象,
主要使用UIDevice.findObject(BySelector)进行使用,其简写是.findObject(By.test"abcd"),By是提供静态工厂方法来构造BySelector 。
1,深度搜索API
PS:同一深度的元素,可以继续点出来,例如 findObject(By.depth(3).text"jhk"); 定位第三层 text=jhk的元素。
搜索范围,depth后面三个api 不能再By里直接用,但是它返回的是BySelector 可以用(By.text"".depth(2,8))来定位某个范围中的元素
2,常规搜索api
Pattern p = Pattern.compile("\\d");正则, \\d代表数字 .compile("3.7")代表数字3到7.
判断元素是否有点击,长按,焦点,滑动等功能
层级关系的api ,
UiDevice
InstrumentationRegistry — 类说明
一个暴露的注册实例,持有instrumentation运行的进程和它的参数。还提供了一种简便的方法调用者的instrumentation, application context和instrumentation参数
@Test
public void testInstrumentation(){
Bundle bundle=InstrumentationRegistry.getArguments();//得到目标
instrument.sendStatus(888,bundle);
Context cur_context=instrument.getContext();//当前context
Context tar_context=instrument.getTargetContext();//目标context
PackageManager pm=cur_context.getPackageManager();//得到包管理
Bundle context_bundle=new Bundle();
context_bundle.putString("CUR_CONTEXT", pm.getInstalledPackages(0).get(0).toString());
context_bundle.putString("CUR_CONTEXT", pm.getInstalledPackages(0).get(1).toString());
InstrumentationRegistry.registerInstance(instrument, context_bundle);
Bundle b2=InstrumentationRegistry.getArguments();
instrument.sendStatus(889, b2);
}
@Test
public void testLaunchApp(){
Context context=InstrumentationRegistry.getContext();//得到包的context
PackageManager pm=context.getPackageManager();//得到包管理
List<PackageInfo> packageInfo=pm.getInstalledPackages(0);//整机的 包的信息
List<ApplicationInfo> applicationInfos=pm.getInstalledApplications(0);//整机的applications的信息
Intent mainIntent=new Intent(Intent.ACTION_MAIN,null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);//得到每个应用的入口的activity的信息,然后可以通过context.startActivity来启动
List<ResolveInfo> resolveInfos=pm.queryIntentActivities(mainIntent,0);//通过查询返回每个应用的信息
for(ResolveInfo reinfo:resolveInfos){
String activityName=reinfo.activityInfo.name;
String pkgName=reinfo.activityInfo.packageName;
Intent launchIntent=new Intent();
launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
launchIntent.setComponent(new ComponentName(pkgName, activityName));
context.startActivity(launchIntent);
device.pressBack();
device.pressBack();
device.pressBack();
device.pressBack();
}
}
在启动程序的时候就会先启动一个Application,然后在此Application运行过程中根据情况加载相应的Activity,而
Activity是需要一个界面的。但是Instrumentation并不是这样的。你可以将Instrumentation理解为一种没有图形界面
的,具有启动能力的,用于监控其他类(用Target
Package声明)的工具类。任何想成为Instrumentation的类必须继承android.app.Instrumentation
Bundle主要用于传递数据;它保存的数据,是以key-value(键值对)的形式存在的。
我们经常使用Bundle在Activity之间传递数据,传递的数据可以是boolean、byte、int、long、float、double、string等基本类型或它们对应的数组,也可以是对象或对象数组(参考文档)。当Bundle传递的是对象或对象数组时,必须实现Serializable 或Parcelable接口。、
Context:是一个访问application环境全局信息的接口,通过它可以访问application的资源和相关的类,其主要功能如下:
• 启动Activity
• 启动和停止Service
• 发送广播消息(Intent)
• 注册广播消息(Intent)接收者
• 可以访问APK中各种资源(如Resources和AssetManager等)
• 可以访问Package的相关信息
• APK的各种权限管理
从以上分析可以看出,Context就是一个对APK包无所不知的大管家,大家需要什么,直接问它就可以了
@Test
public void testUiDeviceNewApi() throws IOException, UiObjectNotFoundException {
//1.dumpWindowHierarchy(java.io.OutputStream out)
//生命一个文件,sd卡路径+文件分割+名字 需要在Androidmanifeast.xml中增加sd卡的权限
File file=new File(Environment.getExternalStorageDirectory()+File.separator+"uidump.xml");
if(file.exists()){
file.delete();
try {
file.createNewFile();//创建一个文件
} catch (IOException e) {
e.printStackTrace();
}
}else{
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
OutputStream out=new FileOutputStream(file,true);//文件输出流
device.dumpWindowHierarchy(out);//返回当前界面层级信息的输出流
//2.executeShellCommand(java.lang.String cmd)
device.executeShellCommand("am start -n com.android.settings/.Settings");//启动设置activity
//3.findObject(BySelector selector)
device.wait(Until.findObject(By.text("显示")),20000);
UiObject2 object2=device.findObject(By.text("显示"));
object2.click();
//4.findObject(UiSelector selector)
UiObject object=device.findObject(new UiSelector().text("壁纸"));
object.clickAndWaitForNewWindow();
//5.findObjects(BySelector selector)
Bundle bundle=new Bundle();
List<UiObject2> list_obj=device.findObjects(By.clazz(TextView.class));
for(UiObject2 o:list_obj){
bundle.putString("TEXTVIEW",o.getText());
Log.v("UIDEVICE",o.getText());
}
InstrumentationRegistry.registerInstance(instrument,bundle);//注入
instrument.sendStatus(999,bundle);//发送到测试报告中去
//wait(SearchCondition<R> condition, long timeout)
}
UiObject2
基础动作
手势
Until
Spoon
Spoon.screenshot(activity, "initial_state");
/* Normal test code... */
Spoon.screenshot(activity, "after_login");
指定的标签将被用于识别和比较跨多个测试运行的截图。
当然测试完成你可以把所有截图串起来做一个 GIF 动画图像
// by absolute path string
Spoon.save(context, "/data/data/com.yourapp/your.file");
// or with File
Spoon.save(context, new File(context.getCacheDir(), "my-database.db"));
在测试报告中你只要单击文件名即可获取下载的文件
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission>
@Rule
public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<MainActivity>(MainActivity.class);
Spoon 将运行在所有 adb 可见的设备中。只要是 Android 设备,无论是手机平板,无论多少台设备,都可以分发执行
PS :如果是使用的mac OS系统 记得一定要加上sdk路径,windows的话,是系统变量,就不用了