【译】Android 测试支持库(一)

Android Testing support Library 提供了一个强大的Android 应用测试框架。 library提供了一系列用以快速建立和运行测试代码的APIs,包括Junit4 和 功能性UI测试。支持从IDE或者命令行来使用这些APIs。

获取: 通过Android SDK Manager (Testing Support Library Setup

这篇文章的主要内容:

  • 说明了Android Testing Support Library 提供了哪些工具用以测试
  • 如何在你的测试环境中使用AndroidTestRunner
  • 关于支持库的发布信息

测试支持库 的 特性说明

Android 测试支持库包含以下自动化测试工具:

  • AndroidJUnitRunner: Android 上使用的兼容Junit4 的Test Runner
  • Espresso: UI测试框架;适用于应用内功能性UI测试(functional UI testing)
  • UI Automator: UI测试框架;适用于跨APP 的功能性UI测试,跨越的APP既可以是第三方APP,也可以是系统APP

AndroidJUnitRunner

AndroidJUnitRunner
类是一个 JUnit 测试Runner,它允许你在Android 设备上运行JUnit4 或JUnit3 风格的测试类,这些测试类同时也包含那些使用EspressoUI Automator 测试框架建立的测试类。 AndroidJUnitTestRunner 能安装测试包和被测APP 到设备,并且运行测试,报告测试结果。现在AndroidJUnitTestRunner 已经取代了只支持Junit3测试的InstrumentationTestRunner 的测试类。

AndroidJUnitTestRunner的主要功能包括:

注: AndroidJUnitTestRunner 要求Android2.2(API level 8) 或者更高级别

JUnit 支持

AndroidJUnitTestRunner兼容JUnit3和JUnit4测试(最高支持到4.10)。但是,你最好避免将JUnit3 和 JUnit4 的测试代码放在同一个包下面,这将会导致不可预期的结果。注意如果你正在创建一个Instrumented JUnit4 测试类,那么你必须在测试类上使用@RunWith(AndroidJUnit4.class)注解。

下面的代码片段展示了一个使用JUnit4 风格的Instrumented 测试来验证CalculatorActivity 的 add 方法是否正常运行。

    import android.support.test.runner.AndroidJUnit4;
    import android.support.test.runner.AndroidJUnitRunner;
    import android.test.ActivityInstrumentationTestCase2;

    @RunWith(AndroidJUnit4.class)
    public class CalculatorInstrumentationTest
            extends ActivityInstrumentationTestCase2<CalculatorActivity> {

        @Before
        public void setUp() throws Exception {
            super.setUp();

            // Injecting the Instrumentation instance is required
            // for your test to run with AndroidJUnitRunner.
            injectInstrumentation(InstrumentationRegistry.getInstrumentation());
            mActivity = getActivity();
        }

        @Test
        public void typeOperandsAndPerformAddOperation() {
            // Call the CalculatorActivity add() method and pass in some operand values, then
            // check that the expected value is returned.
        }

        @After
        public void tearDown() throws Exception {
            super.tearDown();
        }
    }

访问instrumentation 信息

你可以使用 InstrumentationRegistry 类来获取和你运行的测试有关的信息。 这个类包含 Instrumentation
对象、目标App 的 Context 对象、测试App 的Context以及传递到你的测试的命令行参数。 当你使用UI Automator 框架编写依赖于Instrumentation 或者 Context 对象的测试用例时,这些信息将会非常有用。

测试过滤(Test filtering)

在你的JUnit 4.x 的测试中,你可以使用一些注解来配置运行的测试。 这些功能可以最大限度的减少你往测试代码中添加模板和条件代码的工作量。 在标准的JUnit 4 注解之外,AndroidJUnitTestRunner 还支持以下Android特有的注解:

  • @RequiresDevice: 指定改测试只在物理设备上运行(而不是模拟器)
  • @SdkSupress: 禁止测试在低于给定API 级别的设备上运行。例如,禁止运行在API level低于18 的设备上运行时可以你写 SDKSupress(minSdkVersion=18)

测试分片 (Test sharding)

AndroidJUnitTestRunner 支持将一个测试套件(test suite) 分割成多个测试片,这样你就可以将属于同一个测试片的测试当做一个组一起运行, 当然,这些测试用例必须在同一个Instrumentation 实例下面。(,under the same Instumentation). 每个测试片使用一个数字索引标记。在运行测试时,可以使用 -e numShards 选项来指定要创建多少个测试片,使用 -e shardIndex 选项来指定要运行哪一个片的测试用例。

例如,为了将测试套件(test suite) 分割成为10片,并且只运行位于第二片的测试,你可以使用一下命令:

adb shell am instrument -w -e numShards 10 -e shardIndex 2

你可以通过查看 API reference 来了解更多关于如何使用Android test runner 的信息。

Espresso 框架

Espresso 测试框架提供了一系列的APIS 用来构建单个应用内测试用户交互的UI测试用例。 它非常使用来了编写白盒类型的自动化测试用例,因为Espresso测试代码必须了解实现代码的细节。

Espresso 测试框架的主要特性包括:

  • 一套丰富的视图和适配器(View and Adapter)匹配API。 查看 View matching 以了解更多信息。
  • 一套用以进行自动化UI交互的action APIs。 查看 Action APIs 以了解更多。
  • 用以提高测试可信度 的 UI 线程同步机制,查看 UI thread synchronization 以获取更多信息。

注: 需要Android2.2(API level 8) 或者更高版本

View matching

Espresso.onView()
使得你可以访问目标app 里的UI 组件并且与之交互。 该方法接收一个Matcher
参数,然后在视图层次树中定位到匹配到的对应的View实例。你可以使用的匹配条件有:

  • view 的类名
  • view 的 content description
  • view 的R.id
  • view 上显示的文本

例如,为了定位到一个ID 为 my_button 的按钮,你可以指定如下的matcher:

    onView(withId(R.id.my_button));

如果搜索成功,onView() 方法就会返回该View 的一个引用,然后你就可以执行actions 并且测试是否符合预期

Adapter matching - 适配器匹配

在一个 AdapterView
的布局中,布局是在运行时动态改变的。如果目标View 位于一个AdapterView 的子类中(如 ListView
或者 GridView),因为当前的视图层次中只加载了一部分布局View,那么onView() 方法将无法工作。

这时,你就可以使用 Espresso.onData()
方法来查找目标View 。该方法会返回AdapterView中的一个元素,然后你可以在该元素上进行 用户操作模拟和断言(assertions)操作。

Action APIs

一般你都是通过在你的app 的用户界面进行一些操作以测试你的应用。而使用ViewActions
API 你将可以非常容易的自动化这些交互操作。 使用这些API 你可以执行的UI操作如下:

  • View click = 视图点击
  • Swipe = 滑动
  • Key and button presses = 按压按键和按钮
  • Typing test = 输入文字
  • Opeing a link =打开一个链接

例如,你可以编写一个测试脚本来模拟输入一个字符串并且按下一个按钮来提交输入的值的几个动作。 ViewInteraction.perform()
DataInteraction.perform()
接受一个或多个ViewAction
参数,并且按照提供他们的次序依次执行这些动作。

    // Type text into an EditText view, then close the soft keyboard
    onView(withId(R.id.editTextUserInput))
        .perform(typeText(STRING_TO_BE_TYPED), closeSoftKeyboard());

    // Press the button to submit the text change
    onView(withId(R.id.changeTextBt)).perform(click());

UI 线程同步

运行与android设备的测试经常会因为时间问题而随机失败。 这个问题 称之为 test flakiness。 在使用 Espresso之前,解决办法是在测试代码让测试sleep 足够长的时间,或者加入一个足够长的超时时间又或者添加失败时不停尝试的代码。 然而,Espresso 测试框架替你处理了Instrumentation
和 UI 线程间的同步问题,这将是你的测试action和测试断言更加具有可信度。
学习 API referenceTesting UI for a Single App 以了解更多.


原文链接:Android Testing Support

说明:1. 所有链接指向原始链接; 2 . 部分名词保留英文

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,658评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,482评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,213评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,395评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,487评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,523评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,525评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,300评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,753评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,048评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,223评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,905评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,541评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,168评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,417评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,094评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,088评论 2 352

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,977评论 25 707
  • Instrumentation介绍 Instrumentation是个什么东西? Instrumentation测...
    打不死的小强qz阅读 7,779评论 2 39
  • afinalAfinal是一个android的ioc,orm框架 https://github.com/yangf...
    passiontim阅读 15,417评论 2 45
  • 上一篇文章写了我对Ubuntu使用的感受,想看点这里,里边在Ubuntu优点中提到了命令行与快捷键,本文就说说我自...
    wyb1995阅读 709评论 1 2