优秀的Java程序测试是什么样的?

图片 4

本文由码农网 –
小峰原创翻译,转发请看清文末的转发须求,迎接参加大家的付费投稿布置!

简介

测试
在软件开采中是三个很首要的方面,优越的测量试验能够在超级大程度决定三个用到的天数。
软件测量试验中,首要有3大连串:

  • 单元测量检验
    单元测验首倘诺用来测验程序模块,确定保障代码运营正确。单元测量检验是由开采者编写并进行运作测验。平时选取的测量检验框架是
    JUnit 或者
    TestNG。测验用例日常是针对方法
    品级的测量试验。
  • 合併测验
    合龙测验用于检测体系是或不是能平常干活。集成测验也是由开荒者合营实行测验,与单元测验专心测量试验个人代码组件差异的是,集成测量检验是系统开展跨组件测验。
  • 功用性测量检验
    功效性测验是一种质量作保进程以至基于测验软件组件的正式下的由输入获得输出的一种黑盒测量检验。效率性测验日常由分裂的测量试验团队进行测验,测量试验用例的编写制定要依据组件标准,然后依照测量检验输入获得的莫过于出口与梦想值实行比较,剖断功效是不是准确运维。

法定文书档案链接:https://developer.android.google.cn/training/testing/ui-testing/index.html

用作测量试验驱动设计和付出的真诚观者,笔者信赖创制精粹的测验是大家作为Java开采人士能够做的最关键的业务之一。大家写测量检验出于多数缘由:

概述

正文只对
单元测量检验
举办介绍,首要介绍如何在 Android
Studio
下实行单元测验,单元测量试验使用的测验框架为
JUnit

1.前言


客商分界面(UI)测量试验可以保障应用程序满意其意义供给,同临时候质量达到规定的标准贰个高的正式,那样才更只怕成功地被顾客选拔。有一种UI测量检验,轻巧地让测验人士在对象应用程序上实行一文山会海客商操作,来注明它响应的科学。然则,这种手动操作耗费时间、没味且便于失误。更实用的章程是编写UI测量试验,以便自动试行客户操作,进而可重复地、飞速地、可信地运维测量检验。

只顾:强烈建议使用Android
Studio营造测量试验应用程序,因为它提供品类设置、库重视和方便人民群众打包,文章也将借助使用Android
Studio来说述。

经过Android
Studio进行自动化UI测验,须在单身的安卓测量试验目录(src/androidTest/java)下促成测验代码。首先是安卓Gradle插件基于测验代码构建测量试验应用程序,接着在相通设备上独家加载测量试验及目的应用程序。在测验代码中,能够运用UI测量试验框架对目标应用程序模拟客户交互作用,以便具体应用意况下实施测量检验职分。

为了测验安卓应用程序,常常会创设这一个类其余自动化UI测量检验:

  • 仅单个应用程序的UI测验:那体系型的测量检验,能够检查指标应用程序在响应客户分界面交互作用时回来准确的UI,即当客户施行一定操作或输入行为时,验证目的应用程序响应是或不是顺应预期。肖似Espresso的UI测验框架,以编制程序的艺术模拟客户操作,来测量检验复杂的应用程序内相互。
  • 跨多少个应用程序的UI测验:那体系型的测量试验,验证现在不及过去客商应用程序或客户与系统应用程序之间,准确的竞相行为。举个例子,恐怕想要测量试验相机(或暗中认可的安卓相册)通过第三方社交媒体软件,正确分享图像。相同UI
    Automator的UI测量检验框架,协助跨应用人机联作。

上面将介绍怎样运用安卓测量检验扶持库中的工具和APIs来营造那几个类别的自动化测量检验。早前,必需安装安卓测量试验支持库,请参阅下载安卓测验扶持库。

  • 铸就系统的希图。我们知晓输入和输出应该是怎样的,可是大家必要创建什么目的来成功那或多或少呢?代码应该营形成什么样的“形状”?编写测量试验能够让我们知道应该创立什么样的代码。
  • 为了保险先导和不断的不利。让大家的应用程序如愿意地那么运转并且一以贯之地标准比较重大。测量检验应该大力确定保证做到那或多或少。
  • 文书档案。测量试验是系统的文书档案,因为它会注脚它应该做怎么着甚至相应怎么办。

好处

恐怕近些日子仍然有一点都不小学一年级部分开采者未利用
单元测验
对她们的代码进行测量检验,一方面只怕是感觉无需,因为纵然没有张开单元测验,程序依然运营得很好;另一面,也可能有一点点人也确认单元测量试验的裨益,但是出于须求格外的上学开支,所以广大人也是绝非时间照旧说是未有耐烦进行学习······
此地小编想说的是,假诺大家去看下
github
上近些日子主流的开源框架,star
数非常多的项目,日常都有很详细的测验用例。所以说,单元测量检验对于大家的品种开辟,依然挺有裨益的。
有关单元测量试验的功利,小编这里说到几点:

  • 保障代码运维与大家预料的相似,代码不易能够取得保障
  • 程序运维出错开上下班时间,有扶助大家对不当实行查找(因为大家忽略大家测量试验过的代码)
  • 便利升高代码布局划设想计(用于测量试验的用例应力求简约低耦合,因而编写代码的时候,开荒者往往会为了对代码进行测验,将别的耦合的一对举办解耦管理)
    ······

2.仅单个应用程序的UI测量试验


测量检验单个应用程序内的客户人机联作,有辅助确定保证客商不会境遇意外的结果或与应用程序人机联作时体验不佳。纵然急需表达应用程序的UI是还是不是正规运维,应该养成创制客商分界面(UI)测量检验的习贯。

安卓测量检验援救库中的Espresso测验框架,为编写UI测量试验来效仿单个指标应用程序的客商人机联作提供APIs,能够运作于Android
2.3.3(API
10)及以上版本的配备。使用它的首要好处是,能够自动同步被测量试验应用程序UI的测实行为,即开掘主线程空闲时,能够在适当的时候运转测量检验命令,升高测验的可信性。同一时候,也使支付不用加多职务实行机缘相关的代码,比方Thread.sleep()。Espresso测验框架是基于设施的API,且与AndroidJUnitRunner测量检验运转器一同使用。

那正是说“好的测量检验”到底是怎样体统的吗?

JUnit 简介

JUnit is a simple framework to write repeatable tests. It is an
instance of the xUnit architecture for unit testing frameworks.

JUnit
是一个帮助可编写制定重复测验用例的粗略框架。它是
xUnit
单元测量试验架构的二个子集。

  • JUnit
    的施用方法和术语
名称 解释
Assertions 单元测试实用方法
Test Runners 测试实例应当怎样被执行(测试运行器)
Aggregating tests in Suites 合并多个相关测试用例到一个测试套件中(当运行测试套件时,相关用例就会一起被执行)
Test Execution Order 指定测试用例运行顺序
Exception Testing 如何指定测试用例期望的异常
Matchers and assertThat 如何使用 Hamcrest 的匹配器 (matchers) 和更加具备描述性的断言 (assertions)
Ignoring Tests 失能类或方法的测试用例
Timeout for Tests 指定测试用例的最大运行时间(超过这个时间,自动结束测试用例)
Parameterized Tests 测试用例运行多次,每次都使用不同的参数值
Assumptions with Assume 类似断言,但不会使测试用例失败
Rules 为测试用例增加Rules(相当于添加功能)
Theories 使用随机生成的数据使测试用例更加科学严谨
Test Fixtures 为测试方法或者类指定预备的set upclean up方法
Categories 将测试用例组织起来,方便过滤
··· ···
  • JUnit
    的行使方式和术语详细解释

Assertions

  • 断言
    JUnit
    为全数的原始类型和指标,数组(原始类型数组可能指标数组)提供了两个重载的断言方法(assertion method).断言方法的参数第叁个为预期值,第2个为实在运营的值。另七个可选方法的首先个参数是作为战败输出的字符串音信。还应该有三个不怎么有些差距的断言方法:assertThatassertThat的参数有二个可选的曲折新闻输出,实际运作的值和七个
    Matcher
    对象。请知悉assertThat的预期值和骨子里运维值与别的的断言方法地方是倒转的。
    ps:实质上支付中,提议利用
    Hamcrest
    提供的预知方法:assertThat,因为那个点子一方面写出的代码更具可读性,一方面当断言退步时,那么些主意会提交具体的不当提醒新闻。

更多的
Assertions
新闻,请查看文书档案:Assert

Test
Runners

  • 测验运转器
    当一个类被讲明@RunWith只怕合并一个被@RunWith批注的类时,JUnit
    会把测验用例运营在这里类上,并不是停放的运营器上。

ps: JUnit
的暗中同意运转器是 BlockJUnit4ClassRunner
就算类表明为@RunWith(JUnit4.class),则应用的是暗中认可的测量检验运维器
BlockJUnit4ClassRunner

越多详细新闻,请查看文档:@RunWith

Aggregating tests in
Suites

  • 测量试验套件
    动用套件(Suite)作为运转器使得你能够手动建造叁个得以容纳大多类的测验用例。使用测验套件时,你要求创设二个类,然后为其评释上@RunWith(Suite.class)@SuiteClasses(TestClass1.class, ...),那样,当您运转这么些类时,测验套件各种类的测量检验用例就能够整整被施行。

    import org.junit.runner.RunWith;
    import org.junit.runners.Suite;

    @RunWith(Suite.class)
    @Suite.SuiteClasses({

    TestFeatureLogin.class,
    TestFeatureLogout.class,
    TestFeatureNavigate.class,
    TestFeatureUpdate.class
    

    })

    public class FeatureTestSuite {

    // the class remains empty,
    // used only as a holder for the above annotations
    

    }

Test Execution
Order
从 JUnit
4.11版本伊始,JUnit
暗许使用规定的,不可预知性的测量试验用例试行顺序(MethodSorters.DEFAULT)。要转移测量试验用例推行各类,只需轻松为测验类加多@FixMethodOrder表明,并点名一个主意排序法规:
@FixMethodOrder(MethodSorters.JVM):由JVM决定方法实施各样,在分化的JVM上,施行顺序恐怕差异。
@FixMethodOrder(MethodSorters.NAME_ASCENDING):按议程名展开排序(词典序)实行施行。

import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;

@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class TestMethodOrder {

    @Test
    public void testA() {
        System.out.println("first");
    }
    @Test
    public void testB() {
        System.out.println("second");
    }
    @Test
    public void testC() {
        System.out.println("third");
    }
}

Exception
Testing
您哪些验证代码抛出的百般是你所企盼的?验证代码平常走完是很器重,可是保障代码在格外情状下显现也与预期同样也是很关键的,例如:

new ArrayList<Object>().get(0);

那句代码应该抛出三个
IndexOutOfBoundsException异常。@Test表明有三个可选的参数
expected,它能够指导四个Throwable的子类。即便大家期待验证ArrayList能科学抛出四个极其,我们理应如此写:

@Test(expected = IndexOutOfBoundsException.class) 
public void empty() { 
     new ArrayList<Object>().get(0); 
}

参数expected的利用相应严慎。只要测量检验代码中的任何一句抛出叁个IndexOutOfBoundsException十二分,那么地方的测验用例就能透过。对于代码比较长的测量检验用例,推荐应用
ExpectedException 规则。

越多实际情况,请查看:Exception
testing

Matchers and
assertThat

  • assertThat的多个通用格式为:

assertThat([value], [matcher statement])

示例:

assertThat(x, is(3));
assertThat(x, is(not(4)));
assertThat(responseString, either(containsString("color")).or(containsString("colour")));
assertThat(myList, hasItem("3"));

assertThat的第二个参数是三个Matcher.
详细的Matcher介绍,能够查阅以下五个文书档案:

  • JUnit
    Matchers:JUnit
    提供的Matcher
  • Hamcrest
    CoreMatchers:Hamcrest
    提供的Matcher

Ignoring
Tests
是因为一些原因,你不期望测量检验用例运转失利,你只想忽略它,那您只需一时失能那几个测量试验用例就能够。
在 JUnit
中,你能够经过注释方法依然去除@Test讲明来忽视测验用例;但是那样的话测量试验运转器就不会对该测验用例进行连锁报告。另一个方案是为测量检验用例在@Test疏解后面或前边增加上@Ignore讲授;那么测验运转器运转后,就能够输出相关测验用例忽略数目,运维具备测验用例的数额和测验用例失利的多少展现。
注意下@Ignore批注能够指导叁个可选参数(String品类),即令你想记录测量试验用例忽视的原因,能够行使那一个参数:

@Ignore("Test is ignored as a demonstration")
@Test
public void testSame() {
    assertThat(1, is(1));
}

Timeout for
Tests
对于失控也许运营时刻太长的测量检验用例,则自动被感到失利,有二种办法能够完成这么些动作。

  • @Test增加timeout参数
    你可感觉四个测验用例钦赐二个逾期时间(皮秒),在确按时间内,借使测验用例未有运营结束,那么测验用例运行所在线程就能够抛出叁个极其,进而挑起测验退步。

@Test(timeout=1000)
public void testWithTimeout() {
  ...
}

这种达成情势是透过将测量试验用例方法启动在另二个单独的线程中。即便测量试验用例运维时刻抢先规定的岁月,那么测量试验用例就能够倒闭,JUnit
就能够拥塞实施测量试验用例的线程。借使测量试验用例内部实践有能够中断的操作,那么运营测验用例的线程就能够脱离(假设测验用例内部是二个非常循环,那么运营测量试验用例的线程将会永恒运营,而其他测验用例仍在其他的线程上施行)。

  • Timeout Rule (应用到测量检验类的具有测量试验用例)
    Timeout Rule会将同二个超时时间利用到测验类的有着测量检验方法中,而且只要测验用例@Test带有timeout参数,则会叠合到一同(实际测量检验中,并不曾增大的作用,以致tiemout参数并不见到效果,依旧如故以Timeout Rule为准)

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.Timeout;

public class HasGlobalTimeout {
    public static String log;
    private final CountDownLatch latch = new CountDownLatch(1);

    @Rule
    public Timeout globalTimeout = Timeout.seconds(10); // 10 seconds max per method tested

    @Test
    public void testSleepForTooLong() throws Exception {
        log += "ran1";
        TimeUnit.SECONDS.sleep(100); // sleep for 100 seconds
    }

    @Test
    public void testBlockForever() throws Exception {
        log += "ran2";
        latch.await(); // will block 
    }
}

Timeout rule内定的超时时间timeout会选择到持有的测验用例中,包涵此外的@Before@After办法。要是测量检验方法是三个十二万分循环(或许是无计可施响应中断操作),那么@Afte注明的办法恒久不会被实行。

Parameterized
Tests

  • 参数化测量检验
    对于单元测量试验来讲,假如想要同三个测量检验用例中测验多组不一样的数量,那么只能手动试行一次后,校订数据,再进行实行,而利用参数化测量试验的话,则足以将上述的行为实行自动化,我们所供给做的正是提供贰个数目群集,然后创制相应的积极分子变量用来接受数据集合传递过来的数据(在测量试验类布局器中吸取),最终运转测量试验用例时,参数化测验运转器就能相继从数额群集中抽出三个数据,并传给测量试验用例运营:

    //功能类

    public class Math {

      public static int add(int a, int b) {
          return a + b;
      }
    

    }
    //单元测量试验类
    @RunWith(Parameterized.class卡塔尔(قطر‎ //钦命参数化测量试验运转器
    public class MathTest {

      private int a;  //声明成员变量用于接收数据
      private int b;
    
      public MathTest(int a, int b) { //接受集合数据
          this.a = a;
          this.b = b;
      }
    
      @Parameterized.Parameters //创建参数集合
      public static Collection<Object[]> data() {
          Collection<Object[]> collection = new ArrayList<>();
          collection.add(new Object[]{1, 2});
          collection.add(new Object[]{10, 20});
          collection.add(new Object[]{30, 40});
          return collection;
      }
    
      @Test
      public void add() throws Exception {
          assertThat(Math.add(a, b), is(equalTo(30)));
      }
    

    }

Assumptions with
Assume

  • 置于条件
    内置条件与断言近似,只是预见在不相称时,测量检验用例就能倒闭,而放置条件在不相配时只会使测验用例退出。
    内置条件的应用处境是:当你的代码在差异的意况下,大概有两样的结果时,要是你确定后续的测量检验代码是基于某一一定的条件下,才开展测量试验,那么,依据停放条件,就可以完成所需成效。
    譬喻,如果 Windows 平台的文本路线分隔符为””,而 Linux
    平台的为”/”,假如大家的测量试验用例只想在 Linux 平台上拓宽测量试验,那么:

    @Test
    public void filenameIncludesUsername() {

          assumeThat(File.separatorChar, is('/'));
          assertThat(new User("optimus").configFileName(), is("configfiles/optimus.cfg"));
      }
    

假定在 Windows
平台运行测验用例时,assumeThat(File.separatorChar, is('/'))就能够不匹配,那么测量检验用例就径直退出(相通十分机制)。

Rules

  • 规则
    Rules允许为测验用例扩展灵活的尺度照旧是双重定义每种类的测量试验用例行为。测验类能够重复也许再三再四一下任一提供的Rules,只怕本身自定义二个。
Rule Description
TemporaryFolder 创建临时文件夹/文件(测试方法完成后文件被自动删除)
ExternalResource 外部资源Rules的一个基类
ErrorCollector 收集错误信息
Verifier 具备校验功能的一个基类
TestWatcher 具备测试结果记录的一个基类
TestName Rules对象可在测试用例内部获取测试用例方法名
Timeout 为测试类所有测试用例约束最长运行时间
ExpectedException 该类使得测试用例能在方法内判别测试代码是否抛出预期异常
ClassRule 类级别Rule,用于静态变量的注解,在测试类运行时只执行一次
Rule 方法级别的Rule,用于成员变量的注解,在类的每个测试用例执行时都会被执行
RuleChain 为多个Rules指定顺序
TestRule 自定义Rules基类

那边大致介绍下自定义Rules,假如大家要为全数的测验用例输出前后增添”————“,那么,大家须求先创设二个Rule

public class CustomerRule implements TestRule {
    @Override
    public Statement apply(final Statement base, Description description) {
        return new Statement(){
            @Override
            public void evaluate() throws Throwable {
                System.out.println("--------------------------");
                base.evaluate();
                System.out.println();
                System.out.println("--------------------------");
            }
        };
    }
}

下一场把自定义的TestRule应用到测验类里面就可以:

    @Rule
    public CustomerRule customerRule = new CustomerRule();

    @Test
    public void testCustom() {
        assertThat(1, is(1));
    }

更多Rules详细音讯,请查看:Rules

Theories

  • 测量检验理论
    JUnit 中的
    Theories
    可见成三个测量检验理论,该辩驳把测试分为两有的:一个是提供测量试验数据(单个数据用@DataPoint申明,集结数据应用@DataPoints讲明),数据提供者必需为静态成员/方法;另二个是理论自个儿,也即测量检验用例方法。
    Theories
    的测量检验用例允许参数字传送递(普通测量试验用例测量检验方法无法带走参数),参数字传送递法则是第一从数量集合中收取二个充作第一个参数,然后逐条收取群集的要素(包涵已当作参数1的可怜数据)作为第一个参数····
    看下下边包车型客车测验用例就能够相比较清楚
    Theories
    的运作流程:

    @RunWith(Theories.class)
    public class MathTest {
    // @DataPoint
    // public static int arg0 = 1;
    // @DataPoint
    // public static int arg1 = 10;
    // @DataPoint
    // public static int arg2 = 0;

      @DataPoints
      public static int[] args = new int[]{1, 10, 0};
    
      @Theory
      public void divied(int a, int b) throws Exception {
          Assume.assumeTrue(b != 0);
          System.out.println(String.format("a=%d,b=%d", a, b));
          assertThat(Math.divied(a, b), not(equalTo(2)));
      }
    

    }

运转结果如下:

图片 1

result

从地点的测量试验用例能够看出,MathTest提供的多少集合为{1,10,0},所以:
第一次
运营测验用例divied(int a, int b)时,从集结中抽出一个参数,即1会传送给参数a,然后又从集合中抽取叁个参数,也是1,传递给b,然后实行测验用例;
第二次
运行时,参数a维持不改变,然后从新从集结中抽出下三个成分给到b,所以b=10,然后实行测验用例;
第三次
运行时,参数a维持不变,然后从新从集合中抽取下三个成分给到b,所以b=0,然后实践测验用例时,由于不满意Assume置于条件,故测量试验用例不再往下运作,直接退出,所以看到当b=0时,未有打字与印刷结果;
第四次
运行时,由于b在前边第2轮运转时已总体抽取了100%集合数据,所以这时候就轮到参数a收取会集的下三个数额,即a=10,然后就根据前一轮的实践逻辑继续实施下去。

从下面的解析中得以看来,Theories
与 Parameterized
Tests
很周围,两个都贯彻了多组数据协同作用于同五个测验用例的职能,可是两岸的参数字传送递机制仍有比一点都不小的例外的,
Parameterized
Tests
能够提供多维数组的花样相符参数个数顺序,而
Theories
的参数集结中的每一种成分都会同期成效于种种参数;个人感到依然
Parameterized
Tests
更合乎平时的测量检验逻辑。

Test
Fixtures

  • 测量检验设施
    Test
    Fixtures
    是被看作测量试验用例运营的条件的一文山会海对象的备位充数意况,Test
    Fixtures
    为大家提供了4个表明(均用于方法上):
Annotation Description
@BeforeClass 测试类运行时执行
@AfterClass 测试类结束时执行
@Before 每个测试用例执行前先执行
@After 每个测试用例执行后再执行

Categories

  • 分类
    Categories
    见名知意,正是将一多姿多彩测量试验类/测验方法进行归类,每一个类依然接口都能够看做叁个Category,且帮衬项目世袭。
    比方,你内定多个测量检验用例归于SuperClass.class的类别(使用@Category(SuperClass.class)讲解在测量试验类用例上),然后@IncludeCategory(SuperClass.class),那么其余测量检验用例上解说了@Category(SuperClass.class)或者@Category({SubClass.class})的方法都会被实践。
    举个例证:
  1. 率先大家要求定义一个或几个测验项目(即Category)

public class Category {
    public static interface Category01 {}

    public static interface Category02 {}

    public static interface Category01Impl extends Category01{}
}

这里有3种测试Category,其中,类别Category01Impl继续了档案的次序Category01,所以任何@IncludeCategory(Category01.class)的测量试验类,测量试验时也会实施项目为Category01Impl的测量试验用例。

  1. 概念好了测验项目后,大家就需求将这一个品种运用到测验类恐怕测试用例上

public class Tests {
    public static class Test01 {
        @Test
        @Category(Category01.class) //运用到测试用例上
        public void test01() {
            System.out.println("This testCase belongs to Category01");
        }
        @Test
        @Category(Category01Impl.class)//运用到测试用例上
        public void test01Impl() {
            System.out.println("This testCase belongs to Category01Impl");
        }
    }

    @Category(Category02.class)//运用到测试类上,类中所有测试方法都属于`Category02.class`这个类别
    public static class Test02 {
        @Test
        public void test02() {
            System.out.println("This testCase belongs to Category02");
        }
    }
}
  1. 最后,再Categories品种测验运营器上运营必要的测验用例就能够

@RunWith(Categories.class)
@IncludeCategory(Category01.class)
@SuiteClasses({Tests.Test01.class, Tests.Test02.class}) // Note that Category is a kind of Suite
public class CategoryTest {
}

越来越多详细消息,请查看:Categories

2.1.设置Espresso

利用Espresso创设UI测量检验以前,确定保证布局好测验源代码的职分和类型信赖。在安卓app模块的build.gradle文件中,必需设置对Espresso库的依据援引:

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

闭馆测验设施的动画:任由测量试验设施上的连串动漫处于展开状态,大概会促成意外的结果或测量试验败北。通过张开开辟者选项,在安装中关闭动漫及以下有所选项:

  • 窗口动漫缩放
  • 连着动漫缩放
  • 动漫片时间长度缩放

除此而外Espresso提供的主题API外,还想让项目选取到越来越多的风味,请参阅资源。

图片 2

Android Studio 进行单元测验

假设大家供给对叁个 Java Module 实行单元测验,选用
JUnit
框架,则配备步骤如下:

  • build.gralde 中依赖
    JUnit:

dependencies {
     testImplementation 'junit:junit:4.12' //or testCompile
}
  • 创造一个类

public class Math {
    public static int add(int a, int b) {
        return a + b;
    }
}
  • 对上边的类Mathadd方式开展测验
    我们得以手动创造三个Math的测量试验类,不过依附 Android
    Studio,大家可以很方面包车型地铁行使高效操作自动生成测量检验类和测试用例,具体做法为:张开要扩充测验的类公事,双击类名/方法名张开选中,然后按快捷键:<Ctrl-Shift-T>

图片 3

创造测验用例

  • 终极,写上测验代码,进行测验就足以了。

越多详细音讯,请查看官方网址:Building Local Unit
Tests

2.2.创建Espresso测试类

若想创造Espresso测量检验,需依据上面开采形式编写Java类:

  • 透过调用onView()办法找到Activity中想要测验的UI组件(例如,应用程序的登入按键),可能onData()艺术得到AdapterView的子项。
  • 透过调用ViewInteraction.perform()DataInteraction.perform()措施,模拟功能于UI组件的特定客户人机联作和传递客商作为(比如,点击登录开关)。若对同三个UI组件三回九转进行三个操作,使用逗号分隔的法子将它们列在点子参数中。
  • 需要时再也上述手续,来模拟客商在对象应用程序上跨分界面操作。
  • 行使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

给测量试验命名

测量试验的名字根本,非常是从文书档案角度来看的话。大家相应力所能致大声读出测量检验的名字好似一组供给一致。事实上,有一个伟大的IntelliJ插件,叫Enso,它会将您的测验名转移为刚刚坐落于每一个类旁边的语句,那样您就足以清楚地察看您在做哪些。

不要以“test”开端命名测验的名称。那是出自于JUnit前期的后遗症,当须求它实行的时候。你的Test类就要Test文件夹中,在三个尾声有Test这么些单词的类中。会有一个@Test的笺注。咱们通晓那是叁个测量检验。

您也应有制止以“should”或“will”开首。这一个都以忧愁词。既然您早已为这些效用写了一个测量检验,那大家就掌握它“should或will”事业(假诺不可能做事来讲,那大家领略大家须要修补它)。

图片 4

将测验名称作为一个必要。 上面是部分例子

addingNumbersWillSumValuesTogether()
explodesOnNegativeID()
notifiesListenersOnUpdates()

毫无焦灼表明出来。假让你的测量试验名称确实要求十分长的一串单词,那就这样做,只要它能了演说明将发生什么业务。

2.3.配合ActivityTestRule

本节描述怎样创建新的相符JUnit
4样式的Espresso测验,相同的时候选用ActivityTestRule减弱必要写的样品代码的数码。ActivityTestRule能够让测量检验框架在各种被@Test讲解的测量试验方法和其余@Before表明的艺术调用早先,运转被测量检验的Activity。还可以让框架在测量检验停止后,管理Activity能源自由,并运转具备@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)));
    }
}

测验代码

测量检验将分成3个部分:设置,操作,断言。

设置

对你的测量试验设置代码应该只与在测量检验中被断言的值相关。就算你有多余的装置代码,那就能够搞不清楚它是什么样,而且与测验不相干。

那能够经过七种措施得以达成:

  • 将通用设置移动到使用@Before表明的现实性设置方法。
  • 将重新的安装代码移动到帮扶方法
  • 应用Maker来创立复杂的测量检验对象,并只设置测量试验中有关的值。

小编反复一下:每一种测验的设置某些应该独有与终极被断言的值相关的代码。

倒霉的例证:

@Test
    public void returnsBooksWherePartialTitleMatchesInAnyCast(){
        Bookstore bookstore = new Bookstore();
        Book harryPotterOne = new Book("Harry Potter and The Philosopher Stone");
        bookstore.add(harryPotterOne);
        bookstore.add(new Book("Guardians of the Galaxy"));
        Book harryPotterTwo = new Book("The Truth about HARRY POTTER");
        bookstore.add(harryPotterTwo);
        List<Book> results = bookstore.findByTitle("RY pot");
        assertThat(results.size(), is(2));
        assertThat(results, containsInAnyOrder(harryPotterOne, harryPotterTwo));
    }

书报摊的开始化产生在测量试验中,书本的创造也是。那让测验显示杂乱无章,令人搞不清楚发生了怎么业务。

好的例子:

private Bookstore bookstore = new Bookstore();
private Book aHarryPotterBook = new Book("Harry Potter and The Philosopher Stone");
private Book anotherHarryPotterBook = new Book("The Truth about HARRY POTTER");
private Book aBook = new Book("Guardians of the Galaxy");
@Test
public void returnsBooksWherePartialTitleMatchesInAnyCast(){
    bookstore.add(aHarryPotterBook);
    bookstore.add(aBook);
    bookstore.add(anotherHarryPotterBook);
    List<Book> results = bookstore.findByTitle("RY pot");
    assertThat(results.size(), is(2));
    assertThat(results, containsInAnyOrder(aHarryPotterBook, anotherHarryPotterBook));
}

开始化暴发在字段中,那样在测验中爆发了如何一清二楚。

操作

小菜一碟!最好保险到一行,你要拓宽测验的单身操作。不常候,你特别测验的是出口是何许,即便有个别事物被频仍调用,或然在有些优先操作之后调用的结果是如何,所以那不是八个硬性规定。当读取测验时,客户应该不慢而轻便地能说“将这么些值设置成那样,要是本身试行这些操作/那些操作,那么那是预期的结果”。在上头的例子中,正是bookstore.findByTitle(State of Qatar方法。

断言

利用Hamcrest。
Hamcrest是三个很棒的库,给我们二个畅达的API用来写入测量检验。不会像这样的代码:

assertEquals(results.size(), 2);
assertTrue(results.contains(aHarryPotterBook))
assertTrue(results.contains(anotherHarryPotterBook))

咱俩得以一望而知、轻易地读书像那样的代码:

assertThat(results.size(), is(2));
assertThat(results, containsInAnyOrder(aHarryPotterBook, anotherHarryPotterBook));

这么些至极轻便的例证:Hamcrest有众多光辉的不二等秘书技,使编写复杂测量试验变得比较轻巧,并同意你创制和煦的相配器。

理所必然,理想状态下,大家愿意有贰个独门的预知。那足以让大家知晓大家正在测量试验什么,并证实我们的代码未有意外意况。犹如那篇随笔中所说的那样,这不是二个硬性的规行矩步,因为在一些意况下,那是不能够缺少的,但纵然你有那样多少个的测量试验:

assertThat(orderBook.bids.size(), is(4));
assertThat(orderBook.asks.size(), is(3));
assertThat(orderBook.bids.get(0).price, is(5200));
assertThat(orderBook.asks.get(2).price, is(10000000));
assertThat(orderBook.asks.get(2).isBuy, is(false));

那么要明了测量试验何地失败或哪条断言首要就变得紧Baba多了。

你也足以在Hamcrest中编辑自定义的匹配器,因为Hamcrest可为复杂断言提供五个温婉的消除方案。倘诺你必要在贰个巡回中运作断言,或许您有恢宏的字段要断言,那么四个自定义的相称器可能才是一流之选。

一个测量检验的最关键的一对之一是,当它退步时,哪怕是叁个5岁男女也理应看得出如何地方出了错甚至何地错了。退步的信息绝对不能够粗心浮气。关于那上头的解决措施是:

  • 若是做其余项指标对象相比较,那么保障对象有三个体面包车型客车toString()音信。未有何样比<MyObject
    @ 142131>不相配更糟的了。
  • 想要做的更加好的话,可以对你的指标使用自定义相配器。你能够规范地精通哪些字段未能合营。
  • 确认保证明显为何您要选取和那几个值作比较。比方,即令你正在将三个字段值与数字3000相比,那么为何是3000?你应有费事地通晓那或多或少。显明,这么些数字不是随意得来的,而且还要保险该变量的命名能够突显它的值是什么样得来的。

具有那些都应该是在二个适度的常识范围内。未有严谨规定!

您还大概有啥要增加补充的吗?接待告诉大家。

2.4.运行Espresso测试

能够从Android
Studio或指令行运营Espresso测量检验,确认品种已钦点AndroidJUnitRunner作为暗许设备运转器。

3.Espresso运用详细解释


3.1.访问UI组件

在Espresso与被测量检验应用程序交互从前,必须先钦点UI组件或视图控件。Espresso也支撑给采纳中的特定视图控件和适配器使用Hamcrest相称器。

为了找到视图控件,调用onView()办法,并传到目的视图特有的匹配器,更详实的陈诉请参阅点名视图相称。onView()办法再次来到允许与视图控件测量试验交互作用的ViewInteraction对象,但想要定位RecyclerView构造中的视图控件,调用此方法也许不起效率。因而,可以依据定位AdapterView中视图的指令操作。

注意:Espresso的onView()措施不检讨钦点的视图是不是行得通,而是使用提供的相配器仅寻找当前视图层级。若无发觉相称的,此方法会抛出NoMatchingViewException格外。

下边包车型客车代码片段突显什么编写测量检验代码,完成访谈艾德itText控件、输入文本字符串、关闭虚构键盘和推行开关点击。

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.
    ...
}
3.2.点名视图相配器

通过使用这一个方法能够钦赐视图相称器:

  • 调用ViewMatchers类中的方法,譬喻,通过搜索显示的文本字符串来恒定视图控件,如下所示:

    onView(withText("Sign-in"));
    

    肖似也足以调用withId()主意,并提供视图控件的财富ID(奥迪Q3.id),如上边包车型地铁事例所示:

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

    安卓能源IDs不能够确认保证是天下第一的。假若测量检验中尝试相配被七个视图控件使用的平等财富ID,Espresso会抛出AmbiguousViewMatcherException极度。

  • 采取Hamcrest的Matchers类。能够运用allOf()主意去联合多少个匹配器,比方containsString()instanceOf()格局。这种措施允许更周详地过滤相称结果,如上边的例子所示:

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

    能够行使not关键字来过滤出不合乎相称器的视图,如上面包车型客车例证所示:

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

    在测量检验中应用这么些情势,需导入org.hamcrest.Matchers包。要询问愈来愈多关于Hamcrest的相当,请参阅官方网站。

为了升高Espresso测量检验的质量,请钦定找到对象视图控件需求的蝇头相称消息。比如,假使视图控件通过友好的叙说文本可独一鲜明,就无需再钦赐它归属TextView的实例。

3.3.定位AdapterView中视图

AdapterView控件中的视图,由子视图在运行时动态排列而成。如若想要测验的指标视图在AdapterView(比如ListView,GridView或Spinner)内,onView()形式大概失效,因为方今突显的视图档案的次序构造大概只加载了一些子视图。当时,可以调用onData()艺术得到DataInteraction对象来拜候指标视图成分,由Espresso肩负加载该因素到当前视图档案的次序布局,以至滚动到它所在地方并将它归入宗旨。

注意:Espresso的onData()艺术不反省内定的视图是不是行得通,而是选用提供的相配器仅寻觅当前视图层级。若无发觉相配的,此方法会抛出NoMatchingViewException万分。

上边包车型大巴代码片段呈现,怎么着使用onData()办法结合Hamcrest相称器寻觅列表中包含特定字符串的钦定项。在此个例子中,LongListActivity类通过SimpleAdapter展现字符串列表。

onData(allOf(is(instanceOf(Map.class)),
        hasEntry(equalTo(LongListActivity.ROW_TEXT), is("test input")));
3.4.实行交互作用

调用ViewInteraction.perform()DataInteraction.perform()情势来模拟对UI组件的顾客交互作用,必得传入两个或多少个ViewAction对象作为参数。Espresso按给定顺序依次触发每种交互作用,并在主线程中实践它们。ViewActions类提供一雨后玉兰片帮扶方法来钦赐通用人机联作,间接行使它们将有助于和火速,而不用再单独创设和布署ViewAction对象。能够钦命那样的操作:

  • ViewActions.click():点击视图控件。
  • ViewActions.typeText():点击有个别视图控件,并输入钦赐字符串。
  • ViewActions.scrollTo():滚动到有个别视图控件。目的视图控件必需是ScrollView的等等,且它android:visibility性情的值必需是VISIBLE。对于那一个世袭自AdapterView的视图控件(比方,ListView),onData()艺术能够担任滚动。
  • ViewActions.pressKey():使用钦定Keycode表示按下某键。
  • ViewActions.clearText():清除指标视图控件中的文本。

假若目的视图控件在ScrollView中,那么别的进程操作从前,需调用ViewActions.scrollTo()措施将它显示到屏幕中。此方法,对已经突显的视图控件未有影响。

3.5.Espresso-Intents做单独测验

Espresso-Intents能够作证和宪章应用程序发出的意图,通过拦截发出的意图并替换内容,然后传给被测量试验组件,从而单独测验应用程序、Activity或Service。使用Espresso-Intents测验从前,须求丰裕底下配置到工程的build.gradle文件中:

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

为了测量试验意图,必要创立IntentsTestRule类的叁个实例,它的功效与ActivityTestRule类很相符。在每一次测验早前,它用来最初化Espresso-Intents,终止当前Activity,並且在每趟测验之后自由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的更加多新闻,请参阅安卓测验协理库官互连网的文书档案,也能够下载IntentsBasicSample和IntentsAdvancedSample代码样例。

3.6.Espresso-Web测试WebViews

Espresso-Web能够测量试验Activity中带有的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对象测量试验Activity的同偶然候,启用WebView的JavaScript。在测量检验中,能够选择WebView中显得的HTML元素和模拟客户交互作用,举例将文件输入文本框,然后点击按键。操作完毕以往,能够注解网页上的结果与希望的结果卓殊。

上边包车型大巴代码片段中,描述如何测量试验Activity中id为‘webview’的WebView组件。typeTextInInput_clickButton_SubmitsForm()办法描述了,采取网页上有些<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的越来越多新闻,请参阅安卓测验协助库官互连网的文书档案,也能够下载Espresso
Web code
sample中的上述代码片段。

3.7.验证结实

调用ViewInteraction.check()或者DataInteraction.check()办法来断言,UI中的视图控件与一些期待的意况相相称。它们都必需传入一个ViewAssertion对象作为参数,如果断言失利,Espresso抛出AssertionFailedError万分。

ViewAssertions类为一定的多如牛毛断言提供一文山会海辅助方法,能够利用的总结:

  • doesNotExist:断言当前的视图档期的顺序布局中,未有视图控件相称钦点的正经。
  • matches:断言钦定的视图控件存在于近年来视图档期的顺序构造中,且它的处境极度某个钦定的Hamcrest相配器。
  • selectedDescendentsMatch:断言父视图控件中的有个别钦定子视图控件存在,且它们的状态特别有些钦点的Hamcrest相配器。

上边包车型地铁代码片段描述如何检查UI中突显的文书,与事情未发生前输入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)));
}

4.跨七个应用程序的UI测量试验


顾客界面(UI)测验涉及跨五个应用程序的顾客交互作用,当客商两种操作需经过此外应用程序或系统UI时,验证应用程序行为的不利。比方那样的场所,一个短信应用程序能够让客户输入文本音信,然后运转安卓通信录,以便接纳音信的收件人,最后将调控权交还给原始应用程序,进而提交消息。

上边陈说,如何运用安卓测验援助库提供的UI
Automator测量试验框架,编写那样的UI测验。它的APIs能够与设施上可以看到成分交互作用,不用关注当前的Activity应是哪个。测量试验能够应用方便的叙说符查找UI组件,举个例子那三个组件展现的文本或它的开始和结果陈诉。UI
Automator测量检验框架能够运作于Android 4.3(API
18)及以上版本的设施,是依靠设备的API,且与AndroidJUnitRunner测验运营器一同行使。

4.1.设置UI Automator

利用UI
Automator构建UI测量检验从前,确定保障布局好测验源代码的职分和体系信赖。在安卓app模块的build.gradle文件中,必需设置对UI
Automator库的依据引用:

dependencies {
    ...
    androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.1'
}

为了优化UI
Automator测验,首先应当检核对象应用程序的UI组件,并确认保证它们可被访谈,具体优化细节将要前边描述。

  • 自己争论装置上的UI

    两全测量试验在此之前,检查UI组件在配备上是不是可以看到,来保管测量检验时能访谈那么些组件,进而决断它们是还是不是有可以预知的文书标签或android:contentDescription质量的值,或以上两者。uiautomatorviewer工具提供方便的可视化界面来检查结构的档案的次序结议和查看设备前程中可以预知的UI组件的属性。通过那个新闻,可选取UI
    Automator创立更加细粒度的测量检验。比如,可创设匹配特定可以预知属性的UI选拔器。

    启动uiautomatorviewer工具的手续:

    • 在实质上设备上运转指标应用程序。

    • 将道具与花费机器相连接。

    • 展开命令窗口,然后前往<android-sdk>/tools/目录。

    • 运用那么些命令运转为工人身份具:

      $ uiautomatorviewer
      

    翻看应用程序的UI属性:

    • uiautomatorviewer界面,点击Device Screenshot按钮。
    • 经过左面板中显得的快速照相能够看看由工具识其他UI组件,同期在右上边板中列出质量,在右上边板中展现结构档期的顺序构造。
    • 也足以点击Toggle NAF Nodes按键来查看UI
      Automator无法访谈的UI组件,但能提供的有效消息很有限。

    要打听安卓提供的见怪不怪UI组件类型,请参阅客商分界面。

  • 确认保障Activity可被访谈

    UI
    Automator测量试验框架更相符已落到实处安卓访谈效果的应用程序。若使用View类型的UI成分,或SDK、帮衬库提供的View的子类,无需协和完结访谈作用,因为那些类已经完成了。但某个应用程序使用自定义UI成分提供更增加的客户体验,那些因素不会自动提供访谈效果。如若应用程序包涵View子类(不出自SDK或协理库)的实例,通过产生以下步骤,确认保证给它们增进访谈成效:

    • 始建一个持续自ExploreByTouchHelper的具体类。
    • 通过调用setAccessibilityDelegate()主意,将上面类的实例与钦定自定义UI成分关联。

    给自定义视图成分增多访谈功效的越多指南,请参阅营造可访问的自定义视图控件。想明白更加的多关于安卓可访问性的相通最棒施行,请参阅让应用程序更易访谈。

4.2.创建UI Automator测试类

UI Automator测量检验类应有写成JUnit 4测量检验类。要驾驭越来越多关于创造JUnit
4测验类和利用JUnit
4预感及注脚,请参阅开创建备单元测量检验类。测验类定义早先,加多
@RunWith(AndroidJUnit4.class)讲明,还需求指虞诩卓测验支持库提供的AndroidJUnitRunner类作为默许测量检验运维器。在UI
Automator测验类中落实上边包车型客车花费步骤:

  • 因此调用getInstance()措施并传到Instrumentation对象作为参数,获取UiDevice对象来访谈想要测量试验的装置。
  • 经过调用findObject()措施,获取UiObject对象来拜望设备上呈现的UI组件(举例,前景中当前视图控件)。
  • 由此调用UiObject的措施,对UI组件模拟特定客商交互作用;举个例子,调用performMultiPointerGesture()情势模拟多点触摸手势和setText()主意编辑文本字段。须求时能够频仍调用步骤2和3中的APIs,来测量检验更复杂的客户人机联作,涉及三个UI组件或顾客操作体系。
  • 这个顾客人机联作实践后,检查UI的反响是不是是预期的场地或作为。

在前面的几节上将包罗更详细的牵线。

4.3.运行UI Automator测试

能够从Android Studio或指令行运转UI
Automator测验,确认品种已钦命AndroidJUnitRunner作为默许设备运营器。

5.UI Automator使用详整


5.1.访问UI组件

UiDevice对象是会见和操作设备意况的基本点渠道。测量检验时,能够调用UiDevice的点子来检查种种质量的气象,举个例子当前横竖屏或出示尺寸。也足以采取UiDevice对象进行设备级其余操作,比方强逼设备横竖屏、按方向物理键和按主页及菜单键。

从设备的主显示屏初叶(或配备上选定的其它开端地方)测试是好的做法,可以调用UI
Automator
API提供情势来筛选特定UI成分,并与之互相。上边包车型客车代码片段突显,测验中如何得到UiDevice实例和模拟按主页键:

import org.junit.Before;
import android.support.test.runner.AndroidJUnit4;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.Until;
...

@RunWith(AndroidJUnit4.class)
@SdkSuppress(minSdkVersion = 18)
public class ChangeTextBehaviorTest {

    private static final String BASIC_SAMPLE_PACKAGE
            = "com.example.android.testing.uiautomator.BasicSample";
    private static final int LAUNCH_TIMEOUT = 5000;
    private static final String STRING_TO_BE_TYPED = "UiAutomator";
    private UiDevice mDevice;

    @Before
    public void startMainActivityFromHomeScreen() {
        // Initialize UiDevice instance
        mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());

        // Start from the home screen
        mDevice.pressHome();

        // Wait for launcher
        final String launcherPackage = mDevice.getLauncherPackageName();
        assertThat(launcherPackage, notNullValue());
        mDevice.wait(Until.hasObject(By.pkg(launcherPackage).depth(0)),
                LAUNCH_TIMEOUT);

        // Launch the app
        Context context = InstrumentationRegistry.getContext();
        final Intent intent = context.getPackageManager()
                .getLaunchIntentForPackage(BASIC_SAMPLE_PACKAGE);
        // Clear out any previous instances
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
        context.startActivity(intent);

        // Wait for the app to appear
        mDevice.wait(Until.hasObject(By.pkg(BASIC_SAMPLE_PACKAGE).depth(0)),
                LAUNCH_TIMEOUT);
    }
}

在这里个例子中,@SdkSuppress(minSdkVersion = 18)讲授有利于保险测量试验,如UI
Automator框架供给的,将只运维在Android 4.3(API 18)及以上版本设备。

使用findObject()艺术可获得UiObject,它表示适合给定选拔标准的视图控件。若须求,在为相像应用程序创制的其余测量检验中,能够重复使用该UiObject实例。需注意的是,每便使用UiObject实例来点击UI成分或询问属性,UI
Automator测量检验框架都会寻觅当前展现实行相称。下边包车型客车代码片段浮现,测验中什么创设代表打消开关和允许开关的UiObject实例。

UiObject cancelButton = mDevice.findObject(new UiSelector()
        .text("Cancel")
        .className("android.widget.Button"));
UiObject okButton = mDevice.findObject(new UiSelector()
        .text("OK")
        .className("android.widget.Button"));

// Simulate a user-click on the OK button, if found.
if(okButton.exists() && okButton.isEnabled()) {
    okButton.click();
}
5.2.点名相配器

假设想看望应用程序中钦点UI组件,使用UiSelector类。它表示在脚下UI显示中,查询内定元素。假使开采相称的因素不独有八个,在结构等级次序布局中率先个十三分的要素作为靶子UiObject再次来到。当创设UiSelector时,能够将多少个属性链接在一同,来抓实找出。若是开掘并未相配的UI成分,抛出UiAutomatorObjectNotFoundException至极。

也足以行使childSelector()主意嵌套四个UiSelector实例。譬喻,上面包车型大巴代码示例呈现,测验时怎么在当前UI突显中钦命查找第八个ListView的物色,接着在ListView中查找文本属性是“Apps”的UI成分。

UiObject appItem = new UiObject(new UiSelector()
        .className("android.widget.ListView")
        .instance(0)
        .childSelector(new UiSelector()
        .text("Apps")));

用作一级奉行,若需求钦命个选取器,应该使用财富ID(假若已经定义了的话),并非文件元素或内容陈说符。实际不是颇有因素都有文件成分,比如,Toolbar中的Logo。文本接纳器不可靠,若对UI做眇小转移,大概招致测量检验退步;它也不支持跨差异语言,只怕不能协作翻译后的字符串。在接收器的标准中内定对象情状是立见成效的,举例,接受了一组早就检查过的成分(没有必要再行检查),调用checked()艺术并将参数设置为True。

5.3.实行交互作用

假诺测量试验已经赢得UiObject对象,能够调用在那之中的办法来对协和表示的UI组件实行客户人机联作,举个例子内定那样的操作:

  • click():点击UI成分可知范围的主干。
  • dragTo():拖动那一个指标到自由地方。
  • setText():在消释可编写制定控件的原委之后,设置新的文本。相反的,clearTextField()格局消逝可编写制定控件内的幸存文本。
  • swipeUp():对UiObject实践上滑操作。相同的,swipeDown()swipeLeft()swipeRight()方法会试行相应操作。

UI
Automator测量试验框架没有必要利用Shell命令发送Intent或运维Activity,而是通过getContext()方法得到Context对象。下边包车型客车代码片段显示,测量检验中如何行使Intent运营被测量试验的应用程序。当只对测量检验总计器应用程序感兴趣,而不关怀运营器时,这么些措施展本领有用。

public void setUp() {
    ...

    // Launch a simple calculator app
    Context context = getInstrumentation().getContext();
    Intent intent = context.getPackageManager()
            .getLaunchIntentForPackage(CALC_PACKAGE);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
            // Clear out any previous instances
    context.startActivity(intent);
    mDevice.wait(Until.hasObject(By.pkg(CALC_PACKAGE).depth(0)), TIMEOUT);
}
5.4.对聚焦试行人机联作

假设想要对成分的集合(举例,音乐特辑中的歌曲或收件箱中的邮件)模拟顾客人机联作,还不错UiCollection类。为了创建UiCollection对象,钦定叁个UiSelector来搜索UI容器或任何子UI成分的包装器,举个例子包罗子UI成分的构造视图控件。下面包车型大巴代码片段展示,测验中如何组织UiCollection来表示展现在FrameLayout中的录像特辑:

UiCollection videos = new UiCollection(new UiSelector()
        .className("android.widget.FrameLayout"));

// Retrieve the number of videos in this collection:
int count = videos.getChildCount(new UiSelector()
        .className("android.widget.LinearLayout"));

// Find a specific video and simulate a user-click on it
UiObject video = videos.getChildByText(new UiSelector()
        .className("android.widget.LinearLayout"), "Cute Baby Laughing");
video.click();

// Simulate selecting a checkbox that is associated with the video
UiObject checkBox = video.getChild(new UiSelector()
        .className("android.widget.Checkbox"));
if(!checkBox.isSelected()) checkbox.click();
5.5.对可滑动的视图施行人机联作

接纳UiScrollable类在显示屏上效仿竖向或横向滑动。当UI元素坐落于荧屏之外,且供给滑动使其步向视图控件时,那几个技艺很有扶助。上面包车型地铁代码片段展示,怎么样模拟设置菜单的猛降和点击About tablet的选项:

UiScrollable settingsItem = new UiScrollable(new UiSelector()
        .className("android.widget.ListView"));
UiObject about = settingsItem.getChildByText(new UiSelector()
        .className("android.widget.LinearLayout"), "About tablet");
about.click();
5.6.验证结出

InstrumentationTestCase世襲自TestCase,所以可选用规范的JUnit断言方法,来测量检验应用程序中的UI组件是或不是重临预期的结果。上边包车型客车代码片段呈现,测量检验中如何能够稳固总计器应用程序中的多少个按键,按梯次点击它们,然后验证是不是出示精确的结果。

private static final String CALC_PACKAGE = "com.myexample.calc";

public void testTwoPlusThreeEqualsFive() {
    // Enter an equation: 2 + 3 = ?
    mDevice.findObject(new UiSelector()
            .packageName(CALC_PACKAGE).resourceId("two")).click();
    mDevice.findObject(new UiSelector()
            .packageName(CALC_PACKAGE).resourceId("plus")).click();
    mDevice.findObject(new UiSelector()
            .packageName(CALC_PACKAGE).resourceId("three")).click();
    mDevice.findObject(new UiSelector()
            .packageName(CALC_PACKAGE).resourceId("equals")).click();

    // Verify the result = 5
    UiObject result = mDevice.findObject(By.res(CALC_PACKAGE, "result"));
    assertEquals("5", result.getText());
}

6.总结


UI测验由于是盲目跟风顾客操作,所以归属黑盒测验范畴。平常都以请专门的学业测量检验人士,设计测量检验用例来覆盖各类意况,并手动操作设备来产生用例。由于手动操作归于重复、无才能含量的体力专门的学问,能够经过代码来促成自动化,解放测量检验职员的劳力,让她们小心于兼顾更全更加好的测量试验用例。

You can leave a response, or trackback from your own site.

Leave a Reply

网站地图xml地图