1. InstrumentationRegistry类
1.1. 类说明:
一个暴露的注册实例,持有instrumentation运行的进程和参数,还提供了一种简便的方法调用instrumentation, application context和instrumentation参数。
1.2 相关API
返回类型 | API |
static Bundle | getArguments(): 返回一个instrumentation参数副本 |
static Context | getContext(): 返回instrumentation对应包的Context |
static Instrumentation | getInstrumentation(): 返回当前运行的instrumentation |
static Context | getTargetContext(): 返回一个目标应用程序的Context |
static void | registerInstance(Instrumentation instrumentation, Bundle arguments):记录或暴露当前instrumentation运行和instrumentation参数包的副本,存储在注册中心 |
1.3 简单示例
1.3.1
package com.test.auto.hellouiautomator;
import android.app.Instrumentation;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import android.support.test.uiautomator.UiDevice;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.io.IOException;
/**
* Created by auto on 16/3/3.
*/
@RunWith(AndroidJUnit4.class)
public class TestClass01 {
public UiDevice mDevice;
public Instrumentation instrumentation;
@Before
public void setUp(){
instrumentation = InstrumentationRegistry.getInstrumentation();
mDevice = UiDevice.getInstance(instrumentation);
}
@Test
public void testCase01() throws IOException {
//获取运行时的参数
Bundle args = InstrumentationRegistry.getArguments();
//输出到运行报告中
instrumentation.sendStatus(100, args);
//获取测试包的Context
Context testContext = InstrumentationRegistry.getContext();
//获取被测应用的Context
Context testedContext = InstrumentationRegistry.getTargetContext();
//通过Context来启动一个Activity,e.g.浏览器
String url = "https://www.baidu.com";
Intent i1 = new Intent(Intent.ACTION_VIEW);
i1.setData(Uri.parse(url));
i1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
testContext.startActivity(i1);
//通过目标Context来启动拨号功能
Intent i2 = new Intent(Intent.ACTION_CALL,Uri.parse("tel:" + 10086));
i2.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
testedContext.startActivity(i2);
Bundle inputBundle = new Bundle();
inputBundle.putString("key", "value");
//注入一个Bundle
InstrumentationRegistry.registerInstance(instrumentation, inputBundle);
//获取运行参数
Bundle outBundle = InstrumentationRegistry.getArguments();
//输出到结果报告中
instrumentation.sendStatus(110,outBundle);
}
}
1.3.2 运行结果
am instrument -w -r -e test 123 com.test.auto.hellouiautomator
2. UiDevice新增API
2.1 API 介绍
返回类型 | API |
void | dumpWindowHierarchy(OutPutStream out): 获取当前页面层级到输出流 |
String | executeShellCommand(String cmd): 执行一个shell命令。备注:此方法只支持api21以上,手机需要5.0系统以上 |
UiObject2 | findObject(BySelector selector): 返回第一个匹配条件的对象 |
UiObject | findObject(UiSelector selector): 返回一个匹配条件的代表视图的UiObject对象 |
List<UiObject2> | findObjects(BySelector selector): 返回所有匹配条件的对象 |
<R> R | wait(SearchCondition<R> condition, long timeout): 等待的条件得到满足 |
2.2 代码示例
package com.test.auto.hellouiautomator;
import android.app.Instrumentation;
import android.os.Bundle;
import android.os.Environment;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.UiObjectNotFoundException;
import android.support.test.uiautomator.UiSelector;
import android.support.test.uiautomator.Until;
import android.widget.TextView;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
/**
* Created by auto on 16/3/3.
*/
@RunWith(AndroidJUnit4.class)
public class TestClass01 {
public UiDevice mDevice;
public Instrumentation instrumentation;
@Before
public void setUp(){
instrumentation = InstrumentationRegistry.getInstrumentation();
mDevice = UiDevice.getInstance(instrumentation);
}
@Test
public void testCase01() throws IOException, UiObjectNotFoundException {
//dumpWindowHierarchy(OutPutStream out)
File file = new File(Environment.getExternalStorageDirectory()+File.separator+"dump.xml");
if(file.exists()){
file.delete();
}
file.createNewFile();
OutputStream outputStream = new FileOutputStream(file);
mDevice.dumpWindowHierarchy(outputStream);
//executeShellCommand(String cmd)
mDevice.executeShellCommand("am start -n com.tencent.mobileqq/.activity.SplashActivity ");
//findObject(BySelector selector)
mDevice.wait(Until.findObject(By.text("联系人")),2000);
UiObject2 uiObject2 = mDevice.findObject(By.text("联系人"));
uiObject2.click();
//findObject(UiSelector selector)
UiObject uiObject = mDevice.findObject(new UiSelector().text("短信"));
uiObject.click();
//findObjects(BySelector selector)
List <UiObject2> uiObject21 = mDevice.findObjects(By.clazz(TextView.class));
Bundle bundle = new Bundle();
for (UiObject2 a:uiObject21) {
bundle.putString("TextView", a.getText());
}
instrumentation.sendStatus(123,bundle);
}
}
2 UiAutomator2 - UiObject2
![](https://i-blog.csdnimg.cn/blog_migrate/b38e959623ce477c7ebc274fc3388f8e.png)
3 UiObject2 API
返回 | API [ 基础动作 ] | 说明 |
void | clear() | 清除编辑框里的内容 |
void | click() | 点击一个对象 |
<R> R | clickAndWait(EventCondition<R> condition, long timeout) | 点击一个对象然后等待在超时时间内条件成立则通过,否则抛出异常 |
void | drag(Point dest) | 拖拽这个对象到指定位置 |
void | drag(Point dest, int speed) | 自定义速度拖拽这个对象到指定位置,速度:像素数/秒 |
void | longClick() | 执行一个长时间点击这个对象动作 |
boolean | scroll(Direction direction, float percent) | 对该对象执行一个滚动动作 |
boolean | scroll(Direction direction, float percent, int speed) | 自定义滚动速度对该对象执行一个滚动动作 |
void | legacySetText(java.lang.String text) | 设置文本内容通过发送keycode |
void | setText(java.lang.String text) | 设置文本内容如果这个对象是一个可编辑的字段 |
返回 | API [ 手势 ] | 说明 |
void | pinchClose(float percent) | 对该对象执行关闭手势 |
void | pinchClose(float percent, int speed) | 自定义速度对该对象执行关闭手势 |
void | pinchOpen(float percent) | 对该对象执行打开手势 |
void | pinchOpen(float percent, int speed) | 自定义速度对该对象执行打开手势 |
boolean | fling(Direction direction) | 对该对象执行一个滑动的手势,Direction代表从哪个方向作为起点 |
boolean | fling(Direction direction, int speed) | 自定义速度对对象执行一个滑动的手势 |
void | swipe(Direction direction, float percent) | 执行一个滑动手势 |
void | swipe(Direction direction, float percent, int speed) | 执行一个滑动手势,可定义滑动速度 |
void | setGestureMargin(int margin) | 以像素为单位设置边缘用于手势 |
void | setGestureMargins(int left, int top, int right, int bottom) | 以像素为单位设置边缘用于手势 |
返回 | API [ 获取属性 ] | 说明 |
String | getApplicationPackage() | 返回应用程序的包名称 |
String | getClassName() | 返回对象的类名称 |
String | getContentDescription() | 返回该对象的内容描述 |
String | getResourceName() | 返回这个对象的完全限定的资源名的id |
String | getText() | 返回此对象的文本值 |
Rect | getVisibleBounds() | 返回该对象的可见范围在屏幕坐标 |
Point | getVisibleCenter() | 返回一个指向这个对象的可见范围的中心 |
返回 | API [ 属性判断 ] | 说明 |
boolean | isCheckable() | 返回此对象是否具有checkable属性 |
boolean | isChecked() | 返回此对象是否具有checked属性 |
boolean | isClickable() | 返回此对象是否具有clickable属性 |
boolean | isEnabled() | 返回此对象是否具有enabled属性 |
boolean | isFocusable() | 返回此对象是否具有focusable属性 |
boolean | isFocused() | 返回此对象是否具有focused属性 |
boolean | isLongClickable() | 返回此对象是否具有longclickable属性 |
boolean | isScrollable() | 返回此对象是否具有scrollable属性 |
boolean | isSelected() | 返回此对象是否具有selected属性 |
返回 | API [ 获取子元素 ] | 说明 |
UiObject2 | findObject(BySelector selector) | 搜索所有的元素在这个对象层级之下,并返回第一个对象与搜索条件相匹配 |
List<UiObject2> | findObjects(BySelector selector) | 搜索所有的元素在这个对象层级之下,并返回所有对象与搜索条件相匹配 |
List<UiObject2> | getChildren() | 返回这个对象下的直接子元素的集合 |
UiObject2 | getParent() | 返回该对象的父类 |
int | getChildCount() | 返回这个对象直属子元素的数量 |
boolean | equals(java.lang.Object object) | 比较两个对象是否相等 |
int | hashCode() | 获取对象的hashCode |
boolean | hasObject(BySelector selector) | 返回该对象是否存在 |
void | recycle() | 回收这个对象 |
<R> R | wait(SearchCondition<R> condition, long timeout) | 等待的条件得到满足 |
<R> R | wait(UiObject2Condition<R> condition, long timeout) | 等待的条件得到满足 |