Android测试(七):Espresso 自动化测试

Android测试(七):Espresso 自动化测试

发布时间 2017年12月20日 虫师

原文:https://developer.android.com/training/testing/ui-testing/espresso-testing.html

在单个应用程序中测试用户交互有助于确保用户在与应用程序进行交互时不会遇到意外的结果,或遇到糟糕的体验。 如果需要验证应用的UI功能是否正常,则应该养成创建用户界面(UI)测试的习惯。

Espresso 测试框架,由Android测试支持库提供,用于编写UI测试的API来模拟单个应用程序内的用户交互。Espresso测试可以在运行Android 2.3.3(API等级10)及更高版本的设备上运行。 使用Espresso的一个关键好处是,它提供了测试操作与正在测试的应用程序的用户界面的自动同步。 Espresso检测主线程是否处于空闲状态,以便能够在适当的时候运行测试命令,从而提高测试的可靠性。此功能还可以减轻在测试代码中添加任何计时变通方法如Thread.sleep() 的麻烦。

Espresso测试框架基于instrumentation的API,并通过AndroidJUnitRunner运行测试。

设置Espresso



在使用Espresso构建UI测试之前,请确保配置测试源代码位置和项目依赖关系,如“ Getting Started with Testing”中所述。

在Android应用程序模块的build.gradle文件中,必须设置对Espresso库的依赖关系引用:

dependencies {
    // Other dependencies ...
    androidTestCompile ‘com.android.support.test.espresso:espresso-core:2.2.2‘
}

关闭测试设备上的动画 - 在测试设备中打开系统动画可能会导致意外的结果,或者可能导致测试失败。 通过打开“开发人员”选项关闭“设置”中的动画,并关闭以下所有选项:

  • 窗口动画比例
  • 过渡动画比例
  • 动画师持续时间比例

如果你希望将项目设置为使用核心API提供的Espresso功能以外的功能,请参阅此资源

创建一个Espresso 测试



要创建Espresso测试,请创建遵循此编程模型的Java类:

1.找到想要在活动中测试的UI组件(例如,应用程序中的登录按钮),调用onView()方法,或者调用AdapterView控件的onData()方法。

2.通过调用ViewInteraction.perform()或DataInteraction.perform()方法并传入用户操作(例如,单击登录按钮),模拟特定的用户交互以在该UI组件上执行。 要在同一UI组件上对多个操作进行排序,请使用方法参数中的逗号分隔列表链接它们。

3.根据需要重复上述步骤,模拟目标应用中多个活动的用户操作。

4.在执行这些用户交互之后,使用ViewAssertions方法来检查UI是否反映了期望的状态或行为。

以下各节将详细介绍这些步骤。

下面的代码片段显示了你的测试类可能如何调用这个基本的工作流程:


onView(withId(R.id.my_view))            // withId(R.id.my_view) is a ViewMatcher
        .perform(click())               // click() is a ViewAction
        .check(matches(isDisplayed())); // matches(isDisplayed()) is a ViewAssertion

使用Espresso和ActivityTestRule



以下部分介绍如何使用JUnit 4样式创建新的Espresso测试,并使用ActivityTestRule来减少需要编写的样板代码的数量。 通过使用ActivityTestRule,测试框架在每个使用@Test注释的测试方法之前以及在使用@Before注释的方法之前启动被测活动。测试完成后,框架处理关闭活动,所有使用@After注释的方法都会运行。

package com.example.android.testing.espresso.BasicSample;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
...

@RunWith(AndroidJUnit4.class)
@LargeTest
public class ChangeTextBehaviorTest {

    private String mStringToBetyped;

    @Rule
    public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(
            MainActivity.class);

    @Before
    public void initValidString() {
        // Specify a valid string.
        mStringToBetyped = "Espresso";
    }

    @Test
    public void changeText_sameActivity() {
        // Type text and then press the button.
        onView(withId(R.id.editTextUserInput))
                .perform(typeText(mStringToBetyped), closeSoftKeyboard());
        onView(withId(R.id.changeTextBt)).perform(click());

        // Check that the text was changed.
        onView(withId(R.id.textToBeChanged))
                .check(matches(withText(mStringToBetyped)));
    }
}

访问UI组建



在Espresso可以与被测试的应用程序进行交互之前,必须先指定UI组件或视图。Espresso支持使用Hamcrest 匹配器在应用程序中指定视图和适配器。

要查找视图,请调用onView()方法并传递一个视图匹配器,该视图匹配器指定要定位的视图。 这在指定视图匹配器中有更详细的描述。 onView()方法返回ViewInteraction对象,允许测试与视图进行交互。 但是,如果要在RecyclerView布局中查找视图,则调用onView()方法可能不起作用。 在这种情况下,请按照在AdapterView中查找视图中的说明进行操作。

注意:onView()方法不检查你指定的视图是否有效。相反,Espresso只搜索当前的视图层次结构,使用matcher提供的视图。如果没有找到匹配,该方法将抛出一个NoMatchingViewException。

下面的代码片段展示了如何编写一个测试来访问EditText字段,输入一个文本字符串,关闭虚拟键盘,然后执行按钮单击。

public void testChangeText_sameActivity() {
    // Type text and then press the button.
    onView(withId(R.id.editTextUserInput))
            .perform(typeText(STRING_TO_BE_TYPED), closeSoftKeyboard());
    onView(withId(R.id.changeTextButton)).perform(click());

    // Check that the text was changed.
    ...
}
指定一个视图匹配器


您可以使用以下方法指定视图匹配器:

  • 在ViewMatchers类中调用方法。 例如,要查找显示的文本字符串来查找视图,可以调用如下所示的方法:
onView(withText("Sign-in"));

也可以调用withId()并提供视图的资源ID(R.id),如下例所示:

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

Android资源ID不保证是唯一的。 如果测试尝试匹配多个视图使用的资源ID,则Espresso会引发AmbiguousViewMatcherException。

  • 使用Hamcrest Matchers类。可以使用AllOf()方法来组合多个匹配器,例如containsString()instanceOf()。 这种方法允许更窄地过滤匹配结果,如以下示例所示:
onView(allOf(withId(R.id.button_signin), withText("Sign-in")));

但是,不能使用关键字来筛选不匹配匹配器的视图,如以下示例所示:

onView(allOf(withId(R.id.button_signin), not(withText("Sign-out"))));

要在测试中使用这些方法,请导入org.hamcrest.Matchers包。 要了解有关Hamcrest匹配的更多信息,请参阅Hamcrest网站

要改善Espresso测试的性能,请指定查找目标视图所需的最低匹配信息。例如,如果某个视图可以通过其描述性文本唯一标识,则不需要指定它也可以从TextView实例分配。

在AdapterView中查找视图

在AdapterView小部件中,视图在运行时动态填充子视图。 如果要测试的目标视图位于AdapterView中(如ListView,GridView或Spinner),则onView()方法可能无法正常工作,因为只有视图的子集可能会加载到当前视图层次结构中。

相反,调用onData()方法来获取DataInteraction对象来访问目标视图元素。 Espresso将目标视图元素加载到当前视图层次结构中。 Espresso还负责滚动目标元素,并将元素放在焦点上。

注意:onData()方法不会检查你指定的项目是否与视图对应。Espresso只搜索当前的视图层次结构。如果找不到匹配,则该方法将引发NoMatchingViewException。

以下代码片段显示了如何使用onData()方法和Hamcrest匹配一起搜索包含给定字符串的列表中的特定行。 在此示例中,LongListActivity类包含通过SimpleAdapter公开的字符串列表。

onData(allOf(is(instanceOf(Map.class)),
        hasEntry(equalTo(LongListActivity.ROW_TEXT), is("test input")));

执行操作



调用 ViewInteraction.perform() 或 DataInteraction.perform() 方法来模拟UI组件上的用户交互。 您必须传入一个或多个ViewAction对象作为参数。 Espresso根据给定的顺序依次触发每个动作,并在主线程中执行它们。

ViewActions类提供了用于指定常用操作的帮助程序方法列表。 可以使用这些方法作为方便的快捷方式,而不是创建和配置单独的ViewAction对象。 你可以指定如下操作:

  • ViewActions.click():点击视图。
  • ViewActions.typeText():点击一个视图并输入一个指定的字符串。
  • ViewActions.scrollTo():滚动到视图。 目标视图必须从ScrollView继承,其android:visibility属性的值必须是可见的。 对于扩展AdapterView的视图(例如,ListView),onData()方法负责为您滚动。
  • ViewActions.pressKey():使用指定的键码进行按键操作。
  • ViewActions.clearText():清除目标视图中的文本。

如果目标视图位于ScrollView的内部,则先执行ViewActions.scrollTo()操作,然后再执行其他操作。 如果已经显示视图,则ViewActions.scrollTo()操作将不起作用。

用Espresso Intents隔离测试你的活动



Espresso Intents可以验证应用程序发送的意图的验证和存根。 通过Espresso Intents,可以通过拦截传出的意图,对结果进行存根并将其发送回被测组件来隔离测试应用程序,活动或服务。

dependencies {
  // Other dependencies ...
  androidTestCompile ‘com.android.support.test.espresso:espresso-intents:2.2.2‘
}

为了测试一个intent,你需要创建一个IntentsTestRule类的实例,它与ActivityTestRule类非常相似。 IntentsTestRule类在每次测试之前初始化Espresso Intents,终止主活动,并在每次测试后释放Espresso Intents。

以下代码片段中显示的测试类为明确的意图提供了一个简单的测试。 它测试建立你的第一个应用程序教程中创建的活动和意图。

@Large
@RunWith(AndroidJUnit4.class)
public class SimpleIntentTest {

    private static final String MESSAGE = "This is a test";
    private static final String PACKAGE_NAME = "com.example.myfirstapp";

    /* Instantiate an IntentsTestRule object. */
    @Rule
    public IntentsTestRule?MainActivity> mIntentsRule =
      new IntentsTestRule?>(MainActivity.class);

    @Test
    public void verifyMessageSentToMessageActivity() {

        // Types a message into a EditText element.
        onView(withId(R.id.edit_message))
                .perform(typeText(MESSAGE), closeSoftKeyboard());

        // Clicks a button to send the message to another
        // activity through an explicit intent.
        onView(withId(R.id.send_message)).perform(click());

        // Verifies that the DisplayMessageActivity received an intent
        // with the correct package name and message.
        intended(allOf(
                hasComponent(hasShortClassName(".DisplayMessageActivity")),
                toPackage(PACKAGE_NAME),
                hasExtra(MainActivity.EXTRA_MESSAGE, MESSAGE)));

    }
}

有关 Espresso Intents的更多信息,请参阅Android测试支持库网站上的Espresso Intent文档。 您还可以下载IntentsBasicSample和IntentsAdvancedSample代码示例。

用Espresso Web测试WebViews



Espresso Web允许测试活动中包含的WebView组件。 它使用WebDriver API来检查和控制WebView的行为。

要开始使用Espresso Web进行测试,需要将以下行添加到应用程序的build.gradle文件中:

dependencies {
  // Other dependencies ...
  androidTestCompile ‘com.android.support.test.espresso:espresso-web:2.2.2‘
}

使用Espresso Web创建测试时,需要在实例化ActivityTestRule对象以测试活动时在WebView上启用JavaScript。 在测试中,可以选择显示在WebView中的HTML元素,并模拟用户交互,例如在文本框中输入文本,然后单击按钮。在完成操作后,你可以验证网页上的结果是否符合预期结果。

在以下代码片段中,这个类测试一个WebView组件,该组件的id值“WebView”在被测试的活动中。 verifyValidInputYieldsSuccesfulSubmission()测试选择网页上的<input>元素,输入一些文本,并检查出现在另一个元素中的文本。

@LargeTest
@RunWith(AndroidJUnit4.class)
public class WebViewActivityTest {

    private static final String MACCHIATO = "Macchiato";
    private static final String DOPPIO = "Doppio";

    @Rule
    public ActivityTestRule mActivityRule =
        new ActivityTestRule(WebViewActivity.class,
            false /* Initial touch mode */, false /*  launch activity */) {

        @Override
        protected void afterActivityLaunched() {
            // Enable JavaScript.
            onWebView().forceJavascriptEnabled();
        }
    }

    @Test
    public void typeTextInInput_clickButton_SubmitsForm() {
       // Lazily launch the Activity with a custom start Intent per test
       mActivityRule.launchActivity(withWebFormIntent());

       // Selects the WebView in your layout.
       // If you have multiple WebViews you can also use a
       // matcher to select a given WebView, onWebView(withId(R.id.web_view)).
       onWebView()
           // Find the input element by ID
           .withElement(findElement(Locator.ID, "text_input"))
           // Clear previous input
           .perform(clearElement())
           // Enter text into the input element
           .perform(DriverAtoms.webKeys(MACCHIATO))
           // Find the submit button
           .withElement(findElement(Locator.ID, "submitBtn"))
           // Simulate a click via JavaScript
           .perform(webClick())
           // Find the response element by ID
           .withElement(findElement(Locator.ID, "response"))
           // Verify that the response page contains the entered text
           .check(webMatches(getText(), containsString(MACCHIATO)));
    }
}

有关Espresso Web的更多信息,请参阅Android测试支持库网站上的Espresso Web文档。您也可以将此代码段作为Espresso Web代码示例的一部分下载。

验证结果



调用ViewInteraction.check()DataInteraction.check()方法来声明UI中的视图匹配某个预期的状态。 必须传递给ViewAssertion对象作为参数。如果断言失败,Espresso将抛出一个AssertionFailedError。

ViewAssertions类提供了用于指定公共断言的帮助器方法列表。 你可以使用的断言包括:

  • doesNotExist:断言当前视图层次结构中没有与指定条件匹配的视图。
  • matches:断言指定的视图存在于当前的视图层次结构中,并且其状态匹配给定的Hamcrest匹配器。
  • selectedDescendentsMatch:声明指定的父视图的子视图存在,并且它们的状态匹配给定的Hamcrest匹配器。

以下代码片段显示如何检查用户界面中显示的文本与先前在EditText字段中输入的文本具有相同的值。

public void testChangeText_sameActivity() {
    // Type text and then press the button.
    ...

    // Check that the text was changed.
    onView(withId(R.id.textToBeChanged))
            .check(matches(withText(STRING_TO_BE_TYPED)));
}

在设备或模拟器上运行Espresso测试



你可以从Android Studio或从命令行运行Espresso测试。 确保将AndroidJUnitRunner指定为项目中的默认检测工具。

要运行Espresso测试,请按照前面章节介绍的步骤运行已测试的测试。

原文地址:https://www.cnblogs.com/jason89/p/9034065.html

时间: 2024-08-03 18:16:28

Android测试(七):Espresso 自动化测试的相关文章

Android测试(六):Android UI自动化测试

Android测试(六):Android UI自动化测试 发布时间 2017年12月20日 虫师 原文:https://developer.android.com/training/testing/ui-testing/index.html 用户界面(UI)测试可以确保你的应用程序满足其功能要求,并达到用户最可能成功采用的高质量标准. UI测试的一种方法是简单地让人类测试人员在目标应用程序上执行一组用户操作,并验证其行为是否正确. 但是,这种手动方法可能耗时.乏味.且容易出错.更有效的方法是编写

Android测试(八):UI Automator 自动化测试

Android测试(八):UI Automator 自动化测试 发布时间 2017年12月20日 虫师 原文:https://developer.android.com/training/testing/ui-testing/uiautomator-testing.html 涉及跨多个应用程序的用户交互的用户界面(UI)测试可以验证应用程序在用户流量跨越其他应用程序或进入系统UI时的行为. 这种用户流程的一个例子是一个消息应用程序,它允许用户输入文本消息,启动Android联系人选择器,以便用户

2014 非常好用的开源 Android 测试工具

2014 非常好用的开源 Android 测试工具 - 开源中国社区 当前有很大的趋势是转向移动应用平台,Android 是最广泛使用的移动操作系统,2014 年大约占 80% 以上的市场.在开发 Android 应用的时候要进行测试,现在市场上有大量的测试工具. 本文主要是展示一系列的开源 Android 测试工具.每个工具都会有相应的简短介绍,还有一些相关的资源.Android 测试工具列表是按照字母来排序的,最后还会介绍几个不是特别活跃的 Android 测试相关的开源项目. 本文提到的开

Android 测试支持库介绍

测试支持库 Android的测试支持库为测试Android应用提供了大量框架.该库提供了一组API快速构建和运行测试代码,包括JUnit4和功能用户界面(UI)测试.可以从Android Studio IDE中或命令行这执行. Android的测试支持库可通过Android SDK管理器获取. 测试支持库特性 AndroidJUnitRunner:兼容JUnit 4测试运行器. Espresso:UI测试框架;适合在单个应用的功能UI测试. UI Automator:UI测试框架;适用于跨应用的

Android测试(一):在Android中测试App

Android测试(一):在Android中测试App 发布时间 2017年12月20日 虫师 原文:https://developer.android.com/training/testing/index.html 测试你的App是开发过程中的重要组成部分.通过对应用程序持续的运行测试,你可以验证程序的正确性.功能和可用在发布之前. 测试还提供了以下优点: 快速反馈失败. 开发周期的早期问题检测. 安全地重构代码,让你优化代码而不用担心回归. 稳定开发速度,帮助你减少技术债务. 这里的特指测试

Android测试:从零开始3—— Instrumented单元测试1

Instrumented单元测试是指运行在物理机器或者模拟机上的测试,这样可以使用Android framework 的API和supporting API.这会在你需要使用设备信息,如app的Context,你可以使用Instrumented单元测试.使用Instrumented单元测试还可以减少mock的代码(当然也可以选择写mock的代码). 一般测试代码放在app/src/androidTest/java/下面.开始测试之前需要在build.gradle配置中引入依赖库: depende

Android测试:从零开始1——简介

参考文档:https://developer.android.com/training/testing/start/index.html 测试分类 使用android studio进行测试,首先需要先了解android测试的分类,新建工程后,项目会默认包含两个测试目录: 1.本地单元测试(Local unit tests) 测试代码位于module-name/src/test/java/,这些测试直接运行在本地JVM上,不需要使用Android框架的API. 2.设备测试(Instrumente

(4.5.4)Android测试TestCase单元(Unit test)测试和instrumentationCase单元测试

Android单元和instrumentation单元测试 Developing Android unit and instrumentation tests Android的单元测试是基于JUnit的.可分为: 1.本地单元测试 - 可以在JVM上运行测试(速度快,优先考虑). 2.Instrumented单元测试 - 需要Android系统 Android的Gradle插件支持在JVM上执行Andr??oid单元测试.它使用特殊版本的android.jar(也称为 Android mocka

Android测试工具ThreadingTest开放API接口说明

ThreadingTest(简称TT)第一期是一款Android白盒测试工具,使用离线检测的方式,在保护用户源代码的基础上,运用插装.第五代覆盖率等技术,为开发工程师与测试工程师提供一套高效可量化.可视化的交流工具.对比其它测试工具,TT在自动化测试时,会对应测试用例自动生成测试用例和代码之间的关系以及函数覆盖率,并且以TT自带的双向追溯图进行展示,在整个自动化测试进行过程中,TT还会以示波器界面可视化的监控整个自动化测试中每时每刻获取的测试数据. 基于其它测试工具测试时,TT还开放了API接口