espresso系列一简介

espresso是什么?

Espresso 测试框架提供了一系列的API用于构建UI测试来测试app内用户流操作。这些API让你可以编写简洁可靠的自动化UI测试。Espresso非常适合用来编写白盒测试,其中测试代码的编写是利用了被测试app中程序代码实现细节。

Espresso测试可运行android 2.3.3(API 10 level)以及更高版本的设备上。使用Espresso的主要好处是,当你运行测试时它提供了自动的同步测试动作与应用程序UI。Espresso会检测你的主线程是否为空闲状态,如果你的没有被利用,这时候他就会抢占主线程运行测试,所以它能够在恰当的时间运行您的测试命令,提高测试的可靠性。这种能力也使您无须添加任何额外的措施,例如在测试代码中加入thread.sleep()

Espresso测试框架基于 instrumentation-based API 并且使用 AndroidJUnitRunner测试驱动运行测试。

Espresso测试框架的关键特性包括:

  • [ ] 提供了灵活的API用于匹配目标app中view和adapter。更多的信息,见View匹配
  • [ ] 大而全的 行为 api(action APIs) 用于自动化UI交互。更多的信息,见行为APIs
  • [ ] UI线程同步来提高测试可靠性。更多信息,见UI线程同步

版本兼容

Espresso 支持如下 API:

代号 API
Froyo 8
Gingerbread 10
Ice Cream Sandwich 15
Jelly Bean 16, 17 ,18
KitKat 19
Lollipop 21

注意:
切记 espresso 有版本断层,并不是全版本支持,请注意你设备android系统的版本,以免造成不必要的免费。
不过最新的android系统版本 espresso都是支持的。

配置espresso

官方文档建议我们在开始配置之前,先看看如何开始测试,我觉得非常有必要,很多新手上来就拿着不知道那找来的例子运行下,就以为自己真的什么都会。这样的真的很不好,官方文档才是最好的老师,让我们一步一步慢慢来。

android是基于JUnit测试框架,单元测试,您可以运行任意本地的单元测试在JVM或instrumented tests在Android设备上。

测试类型

当使用Android studio 编写任何你的测试时,你的测试代码必须进入两个不同的代码目录(源集)。每个模块在您的项目中,Android Studio都包括源集,对应于以下测试类型:

本地单元测试

位于 module-name/src/test/java/.

这些测试运行在本地JVM并没有访问Android框架api功能的权限。
让我们首先开始如何构建本地单元测试。

构建本地单元测试

如果您的单元测试没有依赖或只有简单的依赖Android系统,你应该在本地开发机器上运行您的测试。这种测试方法是有效的,因为它可以帮助你避免加载目标应用程序时的开销以及单元测试需要在一个物理设备或模拟器运行。因此,运行单元测试的时间将大大的减少。使用这种方法,您通常使用mocking 框架,列如Mockito、这可以帮助我们mock测试需要的依赖。

设置测试环境

在你的Android Studio项目时,您必须为本地单元测试存储源文件在 module-name/src/test/java/。当你创建一个新项目,这个目录就已经存在。您还需要为您的项目配置测试依赖,因为需要使用JUnit 4的框架提供标准的api。
如果您的测试需要与Android依赖关系,包括使用Mockito来简化你的单元测试。更多地使用 mock objects在本地的单元测试中,请查看Mocking Android依赖关系。在你的应用程序的顶层目录的build.gradle文件里,您需要指定这些库的依赖关系:

123456
dependencies {    // Required -- JUnit 4 framework    testCompile 'junit:junit:4.12'    // Optional -- Mockito framework    testCompile 'org.mockito:mockito-core:1.10.19'}

创建本地单元测试类

你当地的单元测试类应该写成一个JUnit 4测试类。JUnit是最受欢迎和广泛使用为Java单元测试框架。这个框架的最新版本,JUnit4,允许您在一个比之前的版更清洁和更灵活的方法中编写测试。之前的Android单元测试基于JUnit3框架,使用JUnit4,您不需要扩展junit.framework。TestCase类。你也不需要在测试方法名称包含“test”关键字,或者使用junit的任何类在junit.framework或junit.extensions包。

创建一个基本的JUnit 4测试类,首先需要创建一个Java类,它包含一个或多个测试方法。一个测试方法以@Test annotation标注并且包含代码的实现和验证的代码中包含您想要测试的一个功能组件。

下面的例子展示了如何实现一个本地的单元测试类。测试方法emailValidator_CorrectEmailSimple_ReturnsTrue验证isValidEmail()方法,应用程序返回正确的结果。

12345678910111213
import org.junit.Test;import java.util.regex.Pattern;import static org.junit.Assert.assertFalse;import static org.junit.Assert.assertTrue;

public class EmailValidatorTest {

@Test    public void emailValidator_CorrectEmailSimple_ReturnsTrue() {        assertThat(EmailValidator.isValidEmail("name@email.com"), is(true));    }    ...}

测试组件在应用程序返回预期的结果,使用junit.Assert方法来执行验证检查(或断言)来对比测试组件的状态和一些期望值。为了使测试具有更好的可读的,您可以使用Hamcrest matchers(如 is()和equalTo()方法)来匹配返回的结果与预期的结果。

Mock Android依赖关系

默认情况下,Android插件Gradle执行本地的单元测试与修改后的版本的Android.jar库,它不包含任何实际的代码。相反,从你的单元测试方法调用安卓类抛出异常。这确保你的测试代码和不依赖于任何特定的行为的Android平台(你没有显式地mock)。
您可以使用模拟框架在代码中存根外部依赖关系,以便轻松测试您的组件是否按照预期的方式与依赖关系交互。 通过用模拟对象替换Android依赖项,您可以将单元测试与Android系统的其余部分隔离,同时验证这些依赖关系中的正确方法是否被调用。 Java的Mockito mocking框架(1.9.5及更高版本)提供了与Android单元测试的兼容性。 使用Mockito,您可以配置模拟对象以在调用时返回一些特定值。

要使用此框架将mock对象添加到本地单元测试,请遵循以下编程模型:

  • 在build.gradle文件中包含Mockito库依赖关系,如设置测试环境中所述。
  • 在单元测试类定义的开始,添加@RunWith(MockitoJUnitRunner.class)注释。 这个注释告诉Mockito测试运行器验证你的框架的使用是正确的,并简化了你的模拟对象的初始化。
  • 要为Android依赖项创建模拟对象,请在字段声明之前添加@Mock注释。
  • 要存根依赖关系的行为,可以使用when()和thenReturn()方法指定条件并返回值。

以下示例显示如何创建使用mock上下文对象的单元测试。

12345678910111213141516171819202122232425262728293031
import static org.hamcrest.MatcherAssert.assertThat;import static org.hamcrest.CoreMatchers.*;import static org.mockito.Mockito.*;import org.junit.Test;import org.junit.runner.RunWith;import org.mockito.Mock;import org.mockito.runners.MockitoJUnitRunner;import android.content.SharedPreferences;

@RunWith(MockitoJUnitRunner.class)public class UnitTestSample {

private static final String FAKE_STRING = "HELLO WORLD";

@Mock    Context mMockContext;

@Test    public void readStringFromContext_LocalizedString() {        // Given a mocked Context injected into the object under test...        when(mMockContext.getString(R.string.hello_word))                .thenReturn(FAKE_STRING);        ClassUnderTest myObjectUnderTest = new ClassUnderTest(mMockContext);

// ...when the string is returned from the object under test...        String result = myObjectUnderTest.getHelloWorldString();

// ...then the result should be the expected one.        assertThat(result, is(FAKE_STRING));    }}

要了解有关使用Mockito框架的更多信息,请参阅示例代码中的Mockito API参考和SharedPreferencesHelperTest类。
如果Android.jar中的Android API抛出的异常对于测试有问题,您可以更改行为,以使方法通过在项目的顶级build.gradle文件中添加以下配置来返回null或零:
android { ... testOptions { unitTests.returnDefaultValues = true } }

警告:将returnDefaultValues属性设置为true应该小心。 null/zero 返回值可以在测试中引入回归,这难以调试,并且可能允许失败的测试通过。 只能使用它作为最后的手段。

运行本地测试

要运行本地单元测试,请按照下列步骤操作:

  1. 通过单击工具栏中的 Sync Project,确保您的项目与Gradle同步。
  2. 使用以下方法之一运行测试:
  • 要运行单个测试,请打开“Project”窗口,然后右键单击测试,然后单击RUN。
  • 要测试类中的所有方法,请右键单击测试文件中的类或方法,然后单击Run。
  • 要在目录中运行所有测试,请右键单击目录并选择Run test。
    Gradle的Android插件编译位于默认目录(src / test / java /)中的本地单元测试代码,构建一个测试应用程序,并使用默认的测试运行器类在本地执行它。 然后,Android Studio将在“运行”窗口中显示结果。

Instrumented tests

位于module-name/src/androidTest/java/。
这些都是必须在Android硬件设备或Android模拟器上运行的测试。

仪表化测试内置于在测试下的应用旁边的设备上运行的APK。 系统在同一个过程中运行测试APK和您的应用程序,因此您的测试可以调用方法和修改应用程序中的字段,并自动化用户与您的应用程序的互动。

有关如何创建检测测试的信息,请参阅以下主题:

构建测试单元测试:使用Android依赖项构建复杂的单元测试,这些测试不能满足模拟对象。
自动化用户界面测试:创建测试以验证用户界面在单个应用程序内的用户交互或多个应用程序之间的交互操作正确。
测试应用程序组件集成:验证用户不直接与之交互的组件(例如服务或内容提供者)的行为。

但是,上述的本地单元测试和instrumented tests只是用于区分在本地JVM上运行的测试和在Android平台(在硬件设备或模拟器上)运行的测试之间的术语。 在构建完整测试套件时应该理解的真实测试类型在下表中描述。

Type 子类型 描述
Unit tests Local Unit Tests 本地单元测试在Java虚拟机(JVM)上本地运行的单元测试。当您的测试没有Android框架依赖项或者可以模拟Android框架依赖项时,使用这些测试来最小化执行时间。
Unit tests Instrumented unit tests 测试单元测试在Android设备或模拟器上运行的单元测试。这些测试可以访问Instrumentation信息,例如您要测试的应用程序的上下文。当你的测试有Android依赖,模拟对象不能满足时,使用这些测试。
Integration Tests Components within your app only 您的应用程序中的组件仅当用户执行特定操作或在其活动中输入特定输入时,此类型的测试验证目标应用程序的行为如预期。例如,它允许您检查目标应用程序返回正确的UI输出,以响应用户在应用程序活动中的互动。 Espresso等UI测试框架允许您以编程方式模拟用户操作并测试复杂的应用内用户交互。
Integration Tests Cross-app Components 跨应用程序组件此类型的测试验证不同用户应用程序之间或用户应用程序和系统应用程序之间的交互的正确行为。例如,当用户在Android设置菜单中执行操作时,您可能需要测试您的应用是否正确运行。支持跨应用程序交互的UI测试框架(如UI Automator)允许您为这些场景创建测试。

Test APIs

以下是用于在Android上测试应用的常见API。
JUnit
您应该将您的单元或集成测试类写为JUnit 4测试类。 该框架提供了一种方便的方法来在测试中执行常见的setup, teardown, and assertion操作。

基本的JUnit 4测试类是包含一个或多个测试方法的Java类。 测试方法以@Test注释开始,包含练习和验证要测试的组件中的单个功能(即逻辑单元)的代码。

以下代码段显示了一个示例JUnit 4集成测试,它使用Espresso API对UI元素执行单击操作,然后检查是否显示预期的字符串。

123456789101112131415
@RunWith(AndroidJUnit4.class)@LargeTestpublic class MainActivityInstrumentationTest {

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

@Test    public void sayHello(){        onView(withText("Say hello!")).perform(click());

onView(withId(R.id.textView)).check(matches(withText("Hello, World!")));    }}

在您的JUnit 4测试类中,您可以通过使用以下注释调用测试代码中的部分进行特殊处理:

  • @Before:使用此注释来指定包含测试设置操作的代码块。测试类在每次测试之前调用此代码块。你可以有多个@Before方法,但是测试类调用这些方法的顺序不能保证。
  • @After:此注释指定一个包含测试拆分操作的代码块。测试类在每个测试方法之后调用这个代码块。您可以在测试代码中定义多个@After操作。使用此注释从内存释放任何资源。
  • @Test:使用此注释标记测试方法。单个测试类可以包含多个测试方法,每个测试方法都以此注释作为前缀。
  • @Rule:规则允许您以可重用的方式灵活地添加或重新定义每个测试方法的行为。在Android测试中,将此注释与Android测试支持库提供的测试规则类之一一起使用,例如ActivityTestRule或ServiceTestRule。
  • @BeforeClass:使用此注释为每个测试类指定仅调用一次的静态方法。此测试步骤对于消耗大的操作(例如连接到数据库)很有用。
  • @AfterClass:使用此注释为测试类指定静态方法,仅在类中的所有测试运行后调用。 这个测试步骤对释放在@BeforeClass块中分配的任何资源很有用。
  • @Test(timeout =):一些注释支持传递元素的能力,您可以为其设置值。 例如,您可以为测试指定超时期限。 如果测试开始,但没有在给定的超时期间内完成,它会自动失败。 您必须以毫秒为单位指定超时期限,例如:@Test(timeout = 5000)。
    使用JUnit Assert类来验证对象状态的正确性。 assert方法将您从测试所期望的值与实际结果进行比较,如果比较失败,则抛出异常。 断言类更详细地描述这些方法。

    Android测试支持库

    Android测试支持库提供了一组API,允许您快速构建和运行应用程序的测试代码,包括JUnit 4和功能UI测试。 库包括以下基于工具的API,当您想要自动化测试时,这些API是有用的:

AndroidJUnitRunner
适用于Android的JUnit 4兼容测试运行器。
espresso
一个UI测试框架; 适用于在应用程序内的功能UI测试。
UI automator
适用于系统和已安装应用程序之间跨应用程序功能UI测试的UI测试框架。

断言类

由于Android测试支持库API扩展JUnit,因此可以使用断言方法显示测试结果。断言方法将测试返回的实际值与预期值进行比较,如果比较测试失败,则抛出AssertionException异常。使用断言比记录更方便,并提供更好的测试性能。

为了简化测试开发,您应该使用Hamcrest库,它允许您使用Hamcrest匹配器API创建更灵活的测试。

Monkey 和 monkeyrunner
Android SDK包含两个用于功能级应用测试的工具:

Monkey
这是一个命令行工具,用于向设备发送按键,触摸和手势的伪随机流。您使用Android Debug Bridge(adb)工具运行它,并使用它来压力测试您的应用程序,报告所遇到的错误,或通过使用相同的随机数种子多次运行该工具来重复事件流。
monkeyrunner
此工具是用Python编写的测试程序的API和执行环境。 API包括用于连接到设备,安装和卸载包,截取屏幕截图,比较两个图像以及针对应用运行测试包的功能。使用API​​,您可以编写大量,强大和复杂的测试。您使用monkeyrunner命令行工具运行使用API​​的程序。

构建Android测试的指南

以下文档提供了有关如何构建和运行各种测试类型的更多详细信息:

建立本地单元测试
构建单元测试没有依赖或只有简单的依赖,你可以mock,它运行在本地JVM上。
建筑仪表单元测试
使用Android依赖项构建复杂的单元测试,这对于在硬件设备或模拟器上运行的模拟对象无法满足。
自动化用户界面测试
创建测试以验证用户界面在单个应用程序内的用户交互或多个应用程序之间的交互正确运行。
测试应用程序集成
验证用户不直接与之交互的组件(例如服务或内容提供者)的行为。
测试显示性能
编写测试应用程序UI性能的测试,以确保持续流畅的用户体验。
ok 我们已经看完了 怎么开始android测试,我想大家一定有了很深入的了解了吧
让我们进入正题 配置espresso
在Android应用程序模块的build.gradle文件中,必须为Espresso引入jar依赖:

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

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

  • 在设备上的设置->开发者选项中禁用一下三项设置: > 窗口动画缩放 > 过渡动画缩放 > 动画程序时长缩放
  • 确保你已经安装了最新的 Extras 下的 Android Support Repository
    设置junit为测试驱动框架
    在build.gradle 中 添加
    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

    完整的build.gradle 示例文件如下

    1234567891011121314151617181920212223242526272829303132
    ​android.defaultConfigpply plugin: 'com.android.application'
    
    android {    compileSdkVersion 24    buildToolsVersion rootProject.buildToolsVersion    defaultConfig {        applicationId "com.example.android.testing.espresso.BasicSample"        minSdkVersion 10        targetSdkVersion 24        versionCode 1        versionName "1.0"
    
    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"    }    lintOptions {        abortOnError false    }    productFlavors {    }}
    
    dependencies {    // App dependencies    compile 'com.android.support:support-annotations:' + rootProject.supportLibVersion;    compile 'com.google.guava:guava:18.0'    // Testing-only dependencies    // Force usage of support annotations in the test app, since it is internally used by the runner module.    androidTestCompile 'com.android.support:support-annotations:' + rootProject.supportLibVersion;    androidTestCompile 'com.android.support.test:runner:' + rootProject.runnerVersion;    androidTestCompile 'com.android.support.test:rules:' + rootProject.rulesVersion;    androidTestCompile 'com.android.support.test.espresso:espresso-core:' + rootProject.espressoVersion;}

之后我们只需要在命令行中输入gradle就会帮我们下载依赖运行测试了,对了记着要安装gradle到你的系统中.

最新内容请见作者的GitHub页:http://qaseven.github.io/

时间: 2024-09-13 12:37:01

espresso系列一简介的相关文章

linux网络编程之socket(十三) epoll系列函数简介与select、poll的区别

一.epoll 系列函数简介 #include <sys/epoll.h> int epoll_create(int size); int epoll_create1(int flags); int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);    

espresso系列3--测试实践

前言 前2篇我们已经详细介绍了espresso的架构以及相应的API,相信大家也有了一定的了解,理论讲的再多,还是不如手上自己敲一遍代码. 还是深入浅出系列的套路,让我这个小司机带大家一步一步进入espresso的世界吧. 环境准备 github github,如果你还用svn的话,请放弃阅读本系列文章,太low了,而且本系列的code都是采用google官方的espresso的demo,都来源于github.android studio android studio,这个不用说,目前andro

PIC系列单片机简介

问题描述 一.引言 据统计,我国的单片机年容量已达1-3亿片,且每年以大约16%的速度增长,但相对于世界市场我国的占有率还不到1%.这说明单片机应用在我国才刚刚起步,有着广阔的前景.培养单片机应用人才,特别是在工程技术人员中普及单片机知识有着重要的现实意义. 当今单片机厂商琳琅满目,产品性能各异.针对具体情况,我们应选何种型号呢?首先,我们来弄清两个概念:集中指令集(CISC)和精简指令集(RISC).采用CISC结构的单片机数据线和指令线分时复用,即所谓冯.诺伊曼结构.它的指令丰富,功能较强,

消防辅助利器:“华平高空布控系统”系列装备简介

华平无线应急布控系统成功参与赣北消防实战演练,其前端"高空布控系统"系列装备由可拆解式登高车图像终端.可拆解式高喷车图像终端.便携式路由中心站共同组成,这套"高空瞄准镜"在高空火情精准侦察.降低危险性,缩短反应时间等方面均有出色发挥,优越的性能使其受到各方关注. 下面就从产品功能.主要特点等方面对这三款装备进行全面介绍. 一 可拆解式登高车图像终端 图1:可拆解式登高车图像终端 可拆解式登高车图像终端能够在不影响.不改变外观及内部电路的情况下,快速装配到消防登高车上

【书】《数据库面试笔试宝典系列》简介

[书]<Oracle数据库面试笔试宝典>相关内容 目录 目录 - 1 - 内容介绍 - 8 - 作者简介 - 8 - 序言 - 9 - 前言 - 10 - 上篇 面试笔试经验技巧篇 - 13 - 第1章 求职经验分享 - 13 - 1.1 踩别人没有踩过的坑,犯别人没有犯过的错 - 13 - 1.2 只要肯钻研,就能成大咖 - 14 - 1.3 普通DBA的逆袭经验 - 14 - 第2章 数据库程序员的求职现状 - 15 - 2.1 当前市场对于数据库程序员的需求如何?待遇如何? - 15 -

RDLC系列之一 简介和入门

一.简介 RDLC报表,通过Report Viewer Control来实现,制作微软RDLC报表由以下三部分构成:1.制作自己的DateSet集合(就是报表的数据集):2.制作自己的报表文件.rdlc文件,用于画做报表样式,里面有微软自带的导出和打印功能.制作显示报表的前台页面aspx文件,基本上就是插入一个ReportViewer然后关联上面的.rdlc文件,注意别忘了更新数据源和插入ScriptManager. 这种报表的易用性和可定制性,主要功能:       1.简单易用的控件,特别是

[Apache commons系列]DBUtils简介-3.示例代码

inkfish原创,请勿商业性质转载,转载请注明来源(http://blog.csdn.net/inkfish ). DbUtils是一个小型的类库,这里通过具体实例来说明如何使用DbUtils.示例分为3个类:DbUtilsExample演示了如何使用DbUtils 类:QueryRunnerExample 演示了如何使用QueryRunner .ResultSetHandler :User 类为一个JavaBean,对应于数据库中的表格.示例采用MySQL为数据库,使用JDBC4.0驱动(最

[Apache commons系列]DBUtils简介-2.核心类简介

inkfish原创,请勿商业性质转载,转载请注明来源(http://blog.csdn.net/inkfish ). DbUtils是一个小型的类库,不需要也不值得花太长的时间去熟悉每一个类.DbUtils核心其实只有三个类/接口,即QueryRunner .ResultSetHandler 和DbUtls (官方文档中写的是前两个).(来源:http://blog.csdn.net/inkfish)   一.下面先过一下DbUtils的几个包(package):(来源:http://blog.

[Apache commons系列]DBUtils简介-1.总述

inkfish原创,请勿商业性质转载,转载请注明来源(http://blog.csdn.net/inkfish ). 一言蔽之,DbUtils就是让开发人员更方便的使用JDBC的工具类库,它不是任何一种框架或数据库.(来源:http://blog.csdn.net/inkfish) DbUtils作用有仨: 1.丢一个SQL,给一个结果: 2.把结果包装成Bean.Map.List或Object[]形式: 3.关闭Connection.Statement.ResultSet时候无需写try ca