module:app
apply plugin: 'com.android.application'
2
3 android {
4 compileSdkVersion 23
5 buildToolsVersion "23.0.2"
6
7 defaultConfig {
8 //不要遗漏这句话
9 testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
//要大于等于18
11 minSdkVersion 18
12 targetSdkVersion 23
13 versionCode 1
14 versionName "1.0"
15 }
16 buildTypes {
17 release {
18 minifyEnabled false
19 proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
20 }
21 }
22 }
23
24 dependencies {
25 compile fileTree(dir: 'libs', include: ['*.jar'])
26 testCompile 'junit:junit:4.12'
28 compile 'com.android.support:appcompat-v7:23.0.1'
////引入uiautomator
31 androidTestCompile 'com.android.support.test:runner:0.4'
32 androidTestCompile 'com.android.support.test:rules:0.4'
33 androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.2'
34 }
测试例子:
package QQ;
import java.io.IOException;
import com.android.uiautomator.core.UiDevice;
import com.android.uiautomator.core.UiObject;
import com.android.uiautomator.core.UiObjectNotFoundException;
import com.android.uiautomator.core.UiSelector;
import com.android.uiautomator.testrunner.UiAutomatorTestCase;
public class Test_qq extends UiAutomatorTestCase
{
public void testDemo() throws IOException, UiObjectNotFoundException {
// 启应用
Runtime.getRuntime().exec("am start com.tencent.mobileqq/com.tencent.mobileqq.activity.SplashActivity");
sleep(3000);
// 点击 "动态" tab
UiDevice device = getUiDevice();
int height = device.getDisplayHeight();
int width = device.getDisplayWidth();
device.click(width -50, height-50);
sleep(1000);
// 点击 "好友动态" 按钮
UiObject obj_1 = new UiObject(new UiSelector().description("点击进入好友动态"));
obj_1.click();
sleep(2000);
// 点击 左上角返回 "动态"按钮
UiObject obj_2 = new UiObject(new UiSelector().resourceId("com.tencent.mobileqq:id/ivTitleBtnLeft"));
obj_2.click();
sleep(1000);
// 点击菜单键
device.pressMenu();
sleep(1000);
// 点击退出qq
UiObject obj_3 = new UiObject(new UiSelector().text("退出QQ"));
obj_3.click();
sleep(1000);
// 点击确定
UiObject obj_4 = new UiObject(new UiSelector().text("确定"));
obj_4.click();
}
}
- exec() 这个函数的意思,相当于是在你在输入adb shell 命令后,在Android手机系统的命令行下运行。所以上面这句话的意思和我们打开cmd框输入” adb shell am start * ” 是一样的的效果。
一般来说我们做App的自动化的时候,第一步都是把App打开,这个am start命令的就可以帮我们实现,类似与Monkeyrunner API中的startActivity() 函数。
- UiDevice对象会在API部分详细讲解,它是一个我们在Uiautomator中经常使用的一个对象。
这里我们首先用它获取到当前手机的宽和高的像素。然后观察到 “动态” tab位于右下方,因此在取得右下角的坐标点后,又进行了一个大概的坐标变化(这里为了简单只是向左和向上移动了50像素,如果要精确的可以进行等比转化),然后点击该坐标。
这里之所以用点击坐标的方法,一方面是因为这个控件Uiautomator不支持用API获得实例,另一方面也是想说明在一些控件没有固定的id、text和desc的时候,我们应该怎么处理。
要想操作一个控件(例如),首先得获得一个UiObject对象,而UiObject对象可以通过UiSelector来构造,而UiSelector可以根据控件的id、text、content-desc来进行构造,这里就是用content-desc来构造。
同第三部分的方法,找到id后直接获得到UiObject对象,进行点击。
UiDevice 可以模拟点击home、back、menu 这三个键,代码应该大家都懂的怎么变化了吧。
这一部分也是先通过获取出控件属性中的text值,然后构造出UiObject对象,完成点击。
api列举:
UiDevice
UiDevice用与访问关设备状态的信息,也可以使用这个类来模拟用户在设备上的操作。可以通过下面的方法得到实例:
UiDevice mdevice = getUiDevice();
函数返回值 | 函数体 | 说明 | 实例 |
---|---|---|---|
boolean | click(int x, int y) | 模拟用户在指定位置点击 | mdevice.click(200, 300) 点击屏幕的200,300坐标处 |
String | getCurrentActivityName() | 获得的是应用程序在桌面上显示的名字 | 例如,在qq首页得到的是“QQ”,在微信登录页得到的是“微信”,注意,这个得到的不是Activity的名字 |
String | getCurrentPackageName() | 获得当前显示的应用程序的包名 | 例如,在微信启动的时候,获得的是“com.tencent.mm” |
int | getDisplayHeight() | 获得当前设备的屏幕分辨率的高 | 例如,我的手机1920*1080,得到的是 1920 |
int | getDisplayWighth() | 获得当前设备的屏幕分辨率的宽 | 例如,我的手机1920*1080,得到的是 1080 |
boolean | isScreenOn() | 判断手机当前是否灭屏 | 当手机灭屏的时候,得到是“false”,手机亮屏,得到的是“true” |
void | wakeUp() | 点亮当前屏幕 | 调用后,相当于按下了电源键,如果手机设置了滑动锁屏,滑动锁屏还是在的,不会自动解开 |
boolean | pressBack() | 点击back键 | |
boolean | pressHome() | 点击home键 | |
boolean | pressMenu() | 点击menu键 | |
boolean | pressKeyCode(int keyCode) | 利用keycode值模拟一次按下事件 | 例如,需要按下数字1 数字1的keycode是 KEYCODE_NUMPAD_1,更多keycode可以在http://developer.android.com/intl/zh-cn/reference/android/view/KeyEvent.html |
boolean | swipe(int startX, int startY, int endX, int endY, int steps) | 用指定的步长,从A点滑动B点 | 例如,需要从(10, 10)点用两步滑动到(100, 200)点,则需要mdevice.swipe(10, 10, 100, 200, 2) |
boolean | takeScreenshot(File storePath) | 截取当前屏幕,保存到文件 | 例如,File files = new File(“/sdcard/res.jpg”); mdevice.takeScreenshot(files); 即可将截图保存到sd卡中了。 |
UiSelector
按照一定的条件(例如控件的text值,资源id),定位界面上的元素。UiSelector对象的最终目的是去构造一个UiObject对象。
函数返回值 | 函数体 | 说明 | 用法 |
---|---|---|---|
UiSelector | text(String text) | 根据“控件text属性的内容”构造出UiSelector对象 | 例如,一个控件text的值是“发现”,UiSelector s = new UiSelector().text(“发现”); |
UiSelector | textContains(String text) | 根据“控件text属性包含的内容”构造出UiSelector对象 | 同上例子:UiSelector s = new UiSelector().textContains(“现”); |
UiSelector | textMatches(String regex) | 根据“控件text属性正则表达式的内容”构造出UiSelector对象 | 正则表达式语法参考网上资料即可。 |
UiSelector | textStartsWith(String text) | 根据“控件text属性开始的内容”构造出UiSelector对象 | 同上例子:UiSelector s = new UiSelector().textStartsWith(“发”); |
UiSelector | description(String desc) | 根据“控件content-desc属性的内容”构造出UiSelector对象 | |
UiSelector | descriptionContains(String desc) | 包含** | |
UiSelector | descriptionMatches(String regex) | 正则 | |
UiSelector | descriptionStartsWith(String desc) | 以**开始 | |
UiSelector | resourceId(String id) | 根据资源id获取对象,例如:UiSelector s = new UiSelector().resourceId(“com.tencent.mm:id/b8m”) | |
UiSelector | resourceIdMatches(String regex) | 根据资源id的正则表达式获取对象 |
UiObject
可以理解为 直接操作界面ui元素的实例。
返回值 | 函数 |
---|---|
void | ClearTextField()在可以编辑处清除已经存在的文本内容 |
boolean | click()执行单击 |
boolean | clickAndWaiForNewWindow(long timeout)执行单击,等待窗口出现,等待时间参数中设置 |
boolean | clickAndWaiForNewWindow()点击等待一个新窗口的出现,默认等待时间 |
boolean | clickBottomRight()点击ui元素的右下方 |
boolean | clickTopLeft()点击ui元素的左上方 |
boolean | exists()检查ui 元素是否存在 |
Rect | getBounds()返回ui元素的坐标值 |
UiObject | getChild(UiSelector selector)通过参数中的对象,创建一个新的当前元素的子类ui元素的子类元素 |
int | getChildCount()获取对象下子类ui元素数量 |
String | getContentDescription()读取ui 元素的描述信息值 |
UiObject | getFromParent(UiSelector selector)根据当前参数对象从父类元素获取子类信息 |
String | getPackageName()读取Ui元素的包名称 |
final UiSelector | getSelector()获取selector用作帮助调试 |
String | getText()根据Ui元素获取文本值 |
Rect | getVisibleBounds()返回ui元素的可视范围 |
boolean | isCheckable()检查对象的checkable属性是否为true |
boolean | isChecked()检查对象的checked属性是否为true |
boolean | isClickable()检查对象的clickable属性是否为true |
boolean | isEnabled()检查对象的enabled属性是否为true |