百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

好用的安卓自动化测试框架Espresso

haoteby 2024-12-07 12:34 11 浏览

Android测试概述

  Android自动化测试是应用开发中提升开发效率的一种方式,它可以在短时间内跑完所有的测试方案以及实现各种交互,从而让开发者更加方便和直观的知道代码的实现效果。

  Android自动化测试可以分为单元测试、UI测试、Monkey测试三种,同时也分小中大三种测试。


  单元测试

  单元测试又称为模块测试,是针对程序模块(软件设计的最小单位)来进行正确性检验的测试工作,程序单元是应用的最小可测试部件。

  Android中的单元测试是基于JUnit,可分为本地测试和Instrumented 测试。

  本地测试对应的项目目录是module-name/src/test/java/,本地测试是运行在本地JVM上的,不需要模拟器或者设备的支持Instrumented 测试在项目中对应的目录是module-name/src/androidTest/java/,这个测试包含了Android系统的api,所以要在模拟器或者设备上运行,速度比本地测试慢。


  单元测试最常用的框架就是JUnit跟Mockito组合的测试框架,其中JUnit用来跑主要的测试代码,Mockito可以创建特定测试对象(非对象本身)并设置一些特定的属性供测试使用。

  UI测试

  UI测试是测试应用中的各种交互是否达到了实现的效果。常用的UI测试框架有Espresso和UIAutomator。

  UIAutomator是一个界面测试框架,适用于整个系统上以及多个已安装应用间的跨应用功能界面测试,它提供了一组 API,用于构建在用户应用和系统应用上执行交互的界面测试。

  Espresso是Google的开源自动化测试框架。相对于UIAutomator,它的特点是规模更小、更简洁,API更加精确,编写测试代码简单,容易快速上手。因为他是基于Instrumentation的,所以不能跨App。

  Espresso的使用

  Espresso有三个重要的类:分别是Matchers(匹配器)、ViewAction(界面行为)、ViewAssertions(界面判断)。

  其中Matchers是常常是通过匹配条件来找UI组件或过滤UI,而ViewAction是来模拟用户操作界面的行为,ViewAssertions对模拟行为操作的View进行变换和结果验证。

  执行顺序如下:

  依赖和配置


  在导入好包之后就可以module的AndroidTest包下开始编写自己的UI自动化测试代码了。

  测试界面跳转

  测试界面跳转时需要用的Espresso-Intents库,它是Espresso的扩展程序,支持对被测应用发出的intent进行验证和打桩。

  它与Mockit 类似,但适用于Android Intent,Espresso-Intents有两个比较重要的方法itending()和intended()。

  intending() 该方法可以插桩(设置跳到其他Activity后返回的参数),原来的Activity调用startActivityForResult()触发桩测试。

  intended() 方法是对发送出去的intent进行确认,如果不是给出的intent则会报错。

@Test fun validateIntentSentToPackage() {

user.clickOnView(system.getView(R.id.callButton))

intended(toPackage("com.android.phone"))

}

  异步测试

  Espresso测试有个很强大之处就是它在多个测试操作中是线程安全的,它会等待当前进程的消息队列中的UI事件,并且在任何一个测试操作中会等待其中的异步任务结束才会执行下一个测试。

  Espresso异步测试是要导入以下两个包:


  异步测试的流程

  新建一个类继承IdlingResource:

public class SimpleIdlingResource implements IdlingResource {

private final String mResourceName;

//这个counter值就像一个标记,默认为0

private final AtomicInteger counter = new AtomicInteger(0);

private volatile ResourceCallback resourceCallback;

public SimpleIdlingResource(String resourceName) {

mResourceName = resourceName;

}

@Override

public String getName() {

return mResourceName;

}

@Override

public boolean isIdleNow() {

return counter.get() == 0;

}

@Override

public void registerIdleTransitionCallback(ResourceCallback resourceCallback) {

this.resourceCallback = resourceCallback;

}

//每当我们开始异步请求,把counter值+1

public void increment() {

counter.getAndIncrement();

}

//当我们获取到网络数据后,counter值-1;

public void decrement() {

int counterVal = counter.decrementAndGet();

//如果这时counter == 0,说明异步结束,执行回调。

if (counterVal == 0) {

//

if (null != resourceCallback) {

resourceCallback.onTransitionToIdle();

}

}

if (counterVal < 0) {

//如果小于0,抛出异常

throw new IllegalArgumentException("Counter has been corrupted!");

}

}

}

  新建一个管理类去管理上述类:

public class EspressoIdlingResource {

private static final String RESOURCE = "GLOBAL";

private static SimpleIdlingResource mCountingIdlingResource =

new SimpleIdlingResource(RESOURCE);

public static void increment() {

mCountingIdlingResource.increment();

}

public static void decrement() {

mCountingIdlingResource.decrement();

}

public static IdlingResource getIdlingResource() {

return mCountingIdlingResource;

}

}

  将管理类插入到异步代码中,在异步任务开始前插入代码:

protected void onReqStart(int where) {

//异步开始前

EspressoIdlingResource.increment();

}

  异步任务结束后插入代码:

private void onFinish() {

if(!EspressoIdlingResource.getIdlingResource().isIdleNow()){

EspressoIdlingResource.decrement();

}

}

  在测试代码中注册IdlingRecource:

@Before

public void setUp() throws Exception {

//调用Activity中我们已经设置好的getIdlingresource()方法,获取Idlingresource对象

idlingresource = activityRule.getActivity().getIdlingresource();

//去掉下行注释,只有异步结束后,才进行接下来的测试代码(tests passed)

//注册异步监听,当该idlingresource中的counter标记值为0时才进行接下来的测试代码

Espresso.registerIdlingResources(idlingresource);

@Test

public void onLoadingFinished() throws Exception {

// 不再需要这样的代码

// Thread.sleep(5000);

// 未注册idlingResource时,立即进行test,此时异步并未结束,报错(tests failed)

onView(withId(R.id.text))

.check(matches(withText("success!")));

@After

public void release() throws Exception {

//我们在测试结束后取消注册,释放资源

Espresso.unregisterIdlingResources(idlingresource);

  测试过程中遇到的问题

  ViewAction()中的typeText()使用。

  如果直接调用typeText(),那么它的使用对象就一定是editText,如果是自定义的未继承editText的view使用typeText()时,要在使用前supportsInputMethods(),否则会报错误:

onView(allOf(supportsInputMethods(), isDescendantOfA(withId(R.id.test)))).perform(typeText("111111"))

  在调用完typeText()后最好调用一下 closeSoftKeyboard(),否则会出现某些view在点击时被阻挡而报错。

总结

  自动化测试的目的不仅仅是解放双手,它也可以让开发者提前知道某些小Bug,不用到了测试阶段才被提出来,这样就提升了开发的效率。

相关推荐

Chrome OS 41 用 Freon 取代 X11_chrome os atom

在刚发布的ChromeOS41里,除了常规的Wi-Fi稳定性提升(几乎所有系统的changelog里都会包含这一项)、访客模式壁纸等之外,还存在底层改变。这一更新中Google移除...

苹果iPad Pro再曝光 有望今年六月发布

自进入2015年以后,有关大屏iPad的消息便一直不绝于耳,之前就有不少媒体猜想这款全新的平板电脑将会在三月发布,不过可惜的是我么只在那次发布会上看到了MacBookPro。近日@Ubuntu团队便...

雷卯针对香橙派Orange Pi 5 Max开发板防雷防静电方案

一、应用场景高端平板、边缘计算、人工智能、云计算、AR/VR、智能安防、智能家居、Linux桌面计算机、Linux网络服务器、Android平板、Android游戏机...

Ubuntu Server无法更新问题解决_ubuntu server not found

上周老家的一台运行UbuntuServer的盒子无法连接上了,中秋这两天回来打开,顺手更新一下发现更新报错。提示`E:Releasefileforhttps://mirrors.aliyun...

虚幻引擎5正式版发布:古墓丽影&amp;巫师新作采用、新一代实时渲染

机器之心报道编辑:杜伟、陈萍虚幻引擎5的目标是「助力各种规模的团队在视觉领域和互动领域挑战极限,施展无限潜能」。...

AMD Milan-X双路霄龙7773X平台基准测试曝光 CPU缓存总量超1.5GB

OpenBenchmarking基准测试数据库刚刚曝光了AMDMilan-X双路霄龙7773X平台的跑分成绩,虽然很快就被撤下,但我们还是知晓了高达1.6GB的总CPU缓存。早些时...

ROS机器人建模_ros机器人硬件搭建

...

全网最新的Dify(1.7.2)私有化离线部署教程(ARM架构)

Hello,大家好!近期工作中有涉及到Dify私有化离线部署,特别是针对于一些国产设备。因此特别整理了该教程,实测有效!有需要的小伙伴可以参考下!本文主要针对Dify1.7.2最新版本+国产操作系...

在ubuntu下新建asp.net core项目_创建ubuntu

本文一步步讲述在ubuntu下用visualstudiocode创建asp.netcore项目的过程。step1:环境操作系统:virtualbox下安装的lubuntu。请不要开启“硬件...

在晶晨A311D2处理器上进行Linux硬件视频编码
在晶晨A311D2处理器上进行Linux硬件视频编码

在KhadasVIM4AmogicA311D2SBC上,我更多的时间是在使用Ubuntu22.04。它的总体性能还不错,只不过缺少3D图形加速和硬件视...

2025-08-26 17:22 haoteby

Nacos3.0重磅来袭!全面拥抱AI,单机及集群模式安装详细教程!

之前和大家分享过JDK17的多版本管理及详细安装过程,然后在项目升级完jdk17后又发现之前的注册和配置中心nacos又用不了,原因是之前的nacos1.3版本的,版本太老了,已经无法适配当前新的JD...

电影质量级渲染来了!虚幻引擎5.3正式发布:已开放下载

快科技9月8日消息,日前,Unrealengine正式发布了虚幻引擎5.3,带来了大量全方位的改进。...

2025如何选购办公电脑?极摩客mini主机英特尔系列选购指南

当下,迷你主机的性能越来越强,品类也越来越多。但是CPU是不变的,基本都是AMD和英特尔的。有一个小伙伴在评论区提问,我应该如何在众多机器中选购一台符合自己的迷你主机呢?那今天我们优先把我们的系列,分...

ubuntu 20.04+RTX4060 Ti+CUDA 11.7+cudnn

ububtu添加国内源sudocp/etc/apt/sources.list/etc/apt/sources.list.backupsudovim/etc/apt/sources.lis...

Linux Mint 18将重新基于Ubuntu 16.04 带来更好硬件支持

项目负责人ClementLefebvre在本月6日披露了关于LinuxMint18“Sarah”操作系统的大量信息,包括带来全新扁平化体验的Mint-Y主题。而现在,这款将于年底之前上线的操作...