UiAutomator 在 Android studio 上运用 UI Automator 执行自动化测试

yueminw · 2015年06月14日 · 最后由 吴兴财 回复于 2017年06月07日 · 5120 次阅读
本帖已被设为精华帖!

概念

  • uiautomatorviewer – 一个图形界面工具来扫描和分析应用的 UI 控件。
  • uiautomator – 一个测试的 Java 库,包含了创建 UI 测试的各种 API 和执行自动化测试的引擎。

要使用该工具,需要满足如下条件:

  • Android SDK Tools, Revision 21 or higher
  • Android SDK v22
  • Android Support Repository rev15

安装

  • 安装 Android Studio

  • 打开 Android SDK Manager (Tools Menu | Android),确保安装了 Android testing support library Repository under Extras.

  • 测试目录 The application under test is located in src/main/javaTests are in src/androidTest/java
    测试目录

  • 在 Android Studio 中,选择文件./build.gradle

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:22.1.1'

    // Set this dependency to build and run UI Automator tests
    androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.0'

}
  • 新建一个项目
  • 在 src/androidTest/java 目录下创建测试类
import android.support.test.uiautomator.UiAutomatorTestCase;
import android.support.test.uiautomator.UiObject;
import android.support.test.uiautomator.UiObjectNotFoundException;
import android.support.test.uiautomator.UiSelector;

public class CalculatorTest extends UiAutomatorTestCase {
    public void testDemo() throws UiObjectNotFoundException {
        getUiDevice().pressHome();
        UiObject Calculator = new UiObject(new UiSelector().description("计算器"));

        Calculator.clickAndWaitForNewWindow();
        UiObject seven = new UiObject(new UiSelector().resourceId("com.android.calculator2:id/digit_7"));
        seven.click();
        UiObject plus = new UiObject(new UiSelector().resourceId("com.android.calculator2:id/op_add"));
        plus.click();
        UiObject one = new UiObject(new UiSelector().resourceId("com.android.calculator2:id/digit_1"));
        one.click();
        UiObject result = new UiObject(new UiSelector().resourceId("com.android.calculator2:id/eq"));
        result.click();
        getUiDevice().pressBack();
    }
}

点击执行,这个应用将会在设备上或者模拟器上自动执行,可以在 Run 窗口下显示测试的结果。

  • 添加验证的结果
UiObject resultTextView = new UiObject(new UiSelector().resourceId("com.android.calculator2:id/formula"));
String resultText = resultTextView.getText();
assertEquals("测试7+1=?的计算结果", “8", resultText);
  • 执行

当测试的结果出错,能够看到错误日志

错误日志

测试结果正确,可以在手机上自动执行测试结果。

  • 调试

在验证处添加断点调试

  • 代码中 UI 元素的来源--uiautomatorview

在开始编写测试案例代码之前,需要熟悉待测应用的 UI 元素。可以通过 uiautomatorviewer 工具来获取应用的界面截图并分析。uiautomatorviewer 工具提供了一个便利的方式来查看 UI 布局结构,并且可以查看各个控件的相关属性。利用这些信息可以用来创建 UI 测试代码。

分析待测应用 UI 界面的步骤如下:

  1. 把 Android 手机连接到电脑上
  2. 打开命令行窗口并导航到 SDK 目录 /tools/
  3. 运行如下命令:$ uiautomatorviewer
共收到 32 条回复 时间 点赞

现在调试不用选 remote debug 了?
怎么设定调试能否详细说一下?还是说不用设定,建好有就直接有了?

uiautomator 用 java 写的,直接下断点调试就可以的,不需要做什么。

#2 楼 @xiyue 只知道在 Eclipse 里面运用 UiAutomator,Eclipse 里的 UiAutomator 工程,如何导入到 Android Studio?楼主是否可以把工程发我学习下?谢谢。

尝试了下 没在 as 里 run 起来 uia

@xiyue 求指导。。

#4 楼 @plasma 可以把错误提示粘过来看看

#5 楼 @wenping 按照上面的步骤做就行了。。。

可惜不会 java。做安卓自动化测试我用的 python

@xiyue 楼主,你这部分的代码是如何管理的?合入开发分支么?~
持续集成呢?用 gradle 命令做么?

@xiyue 楼主,你这部分的代码是如何管理的?合入开发分支么?~
持续集成呢?用 gradle 命令做么?

@xiyue 麻烦看下我的报错信息
public class ApplicationTest extends UiAutomatorTestCase { //这里是第 10 行

public void testDemo() throws UiObjectNotFoundException {
getUiDevice().pressHome();
UiObject Calculator = new UiObject(new UiSelector().description("计算器"));

执行结果:
Running tests
Test running started
junit.framework.AssertionFailedError: Exception in constructor: testDemo (java.lang.RuntimeException: Stub!
at com.android.uiautomator.testrunner.UiAutomatorTestCase.(UiAutomatorTestCase.java:5)
at com.example.helloworld.mynewapplication.ApplicationTest.(ApplicationTest.java:10)
at java.lang.reflect.Constructor.newInstance(Native Method)
at junit.runner.BaseTestRunner.getTest(BaseTestRunner.java:118)
at android.test.AndroidTestRunner.getTest(AndroidTestRunner.java:149)
at android.test.AndroidTestRunner.setTestClassName(AndroidTestRunner.java:57)
at android.test.suitebuilder.TestSuiteBuilder.addTestClassByName(TestSuiteBuilder.java:78)
at android.test.InstrumentationTestRunner.parseTestClass(InstrumentationTestRunner.java:444)
at android.test.InstrumentationTestRunner.parseTestClasses(InstrumentationTestRunner.java:425)
at android.test.InstrumentationTestRunner.onCreate(InstrumentationTestRunner.java:371)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4685)
at android.app.ActivityThread.-wrap1(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1404)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5401)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:725)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:615)
)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:555)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1862)

请问 studio 兼容 Eclipse 下的 project 吗?之前看了下好象是不兼容。。。

你好,能贴一下你 build.gradle 脚本的代码吗?我之前是用 ant 来执行 uiautomator 来执行测试的,现在代码迁移到 Android Studio 的时候遇到一些问题。

#14 楼 @raowm520 嗯,好的。谢谢。

#12 楼 @halo_lan 不需要开发的代码,可以单独建项目管理测试

确保安装了 Android testing support library Repository under Extras.?这个哪里安装呢


UiAutomatorTestCase 在 Android studio 里不建议使用了,各位同学还有更好的吗?

#19 楼 @bjj
官方的说明:

UiAutomatorTestCase

extends InstrumentationTestCase

This class is deprecated.
It is no longer necessary to extend UiAutomatorTestCase. You can use getInstance(Instrumentation) from any test class as long as you have access to an Instrumentation instance.

http://developer.android.com/reference/android/support/test/uiautomator/UiAutomatorTestCase.html

官方的新例子:

import android.test.InstrumentationTestCase;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.By;

public class CalculatorUiTest extends InstrumentationTestCase {

    private UiDevice mDevice;

    public void setUp() {
        // Initialize UiDevice instance
        mDevice = UiDevice.getInstance(getInstrumentation());

        // Start from the home screen
        mDevice.pressHome();
        mDevice.wait(Until.hasObject(By.pkg(getHomeScreenPackage()).depth(0)),
    }
}

http://developer.android.com/training/testing/ui-testing/uiautomator-testing.html#accessing-ui-components

楼主,按照你的步骤做了,没有执行效果呢,执行时是编成了APK到手机上的吗?

#21 楼 @carl 新版的 uiautomator 采用的是 instrumentation 的方式,看原来也是编译成 apk 的形式跟测试的 apk 在同一个进程下工作。

#22 楼 @zsx10110
是吗?这样啊,那如果被测应用发生了 crash,则测试程序一定会停止了?我怎么感觉不对劲呢,可以加你微信或 QQ 请教一下吗?感谢!

#20 楼 @chenhengjie123
你怎么看?本文中介绍的 uiautomator 方法有办法像之前那样打包成一个 jar 文件吗?感谢

#20 楼 @chenhengjie123 请问为什么这一行: mydevice.wait(Until.hasObject(By.pkg(getHomeScreenPackage()).depth(0))); 会报错呢? error message "cannot solve getHomeScreenPackage()". 其他引用比如 uidevice, uiobject 的 api 都正常。

我按照你的步骤来的,在虚拟机上没有问题,可以正常运行。
但是换成真机就跑不了了,直接报错。
下面是我出错的

// 我们使用该属性创建一个UiSelector 对象来定位该按钮。
UiObject allAppsButton = new UiObject(new UiSelector().description("Apps"));
// 模拟点击进入全部应用的屏幕
allAppsButton.clickAndWaitForNewWindow();
UiObject appsTab = new UiObject(new UiSelector().text("Apps"));
appsTab.click();
UiScrollable appViews = new UiScrollable(new UiSelector().scrollable(true));
appViews.setAsHorizontalList();
// 在安装目录中找到自己的apk并打开
UiObject settingsApp = appViews.getChildByText(
                new UiSelector().className(android.widget.TextView.class.getName()), "PhoneInfo");
settingsApp.clickAndWaitForNewWindow();

第二行运行点击事件的时候报错
android.support.test.uiautomator.UiObjectNotFoundException: UiSelector[DESCRIPTION=Apps]

真机上就是跑不成功。
不知道有没有人碰到过这个问题

#25 楼 @jinmincn 这个方法没有啊。。亲,要自己写

@xiyue 楼主你好,我之前一直用 eclipse 编写 UIautomator 的测试用例,今尝试 Android Studio(AS),需在命令行下控制用例的执行,请问在 AS 下如何将测试代码打包成 jar 包或者 apk 包呢,对应的执行命令是什么呢?

#17 楼 @xianjin Start the Android SDK Manager.
In the SDK Manager window, scroll to the end of the Packages list, find the Extras folder and, if necessary, expand to show its contents.
Select the Android Support Repository item.
Click the Install packages... button.
讲的 是 Android Support Repository 吧?

恒温 [该话题已被删除] 中提及了此贴 08月03日 10:42
恒温 UIAutomator2.0 简介 中提及了此贴 12月09日 15:55

To honour the JVM settings for this build a new JVM will be forked. Please consider using the daemon: https://docs.gradle.org/2.14.1/userguide/gradle_daemon.html.

FAILURE: Build failed with an exception.

  • What went wrong:
    Unable to start the daemon process.
    This problem might be caused by incorrect configuration of the daemon.
    For example, an unrecognized jvm option is used.
    Please refer to the user guide chapter on the daemon at https://docs.gradle.org/2.14.1/userguide/gradle_daemon.html

    Please read the following process output to find out more:

    Error occurred during initialization of VM
    Could not reserve enough space for object heap
    Error: Could not create the Java Virtual Machine.
    Error: A fatal exception has occurred. Program will exit.

  • Try:
    Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

运行报这个错,怎么解@xiyue 资源不足,可是我运行其他的又正常

jjxu 回复

您好,你遇到的问题解决了吗?我遇到了和你一样的问题,可以帮忙解决一下吗?

jjxu 回复

也是报了这个问题 junit.framework.AssertionFailedError: Exception in constructor: testDemo (java.lang.RuntimeException: Stub!

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册