好用的安卓自动化测试框架Espresso
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,不用到了测试阶段才被提出来,这样就提升了开发的效率。
好用的安卓自动化测试框架Espresso相关推荐
- 【腾讯优测月刊】安卓主流自动化测试框架详解与实践
导语: 随着移动应用发布周期越来越紧凑.安卓品牌机型/屏幕/系统版本等碎片化日益严重,移动测试工程师的工作量日益剧增.自动化测试or手工测试?这个前些年争执不休的话题,近年来随着云测试平台的崛起似乎已 ...
- Robotium自动化测试框架实用教程(图)
一.简介 Robotium是一款国外的Android自动化测试框架,主要针对Android平台的应用进行黑盒自动化测试,它提供了模拟各种手势操作(点击.长按.滑动等).查找和断言机制的API,能够对各 ...
- python接口测试_Python接口自动化测试框架实战开发(一)
目录 一丶叙述 二丶接口基础知识 三丶接口测试工具 四丶Fiddler的使用 五丶unittest使用 六丶mock服务入门到实战 七丶接口自动化框架设计到开发 一丶叙述 1.项目介绍 整个项目分为四 ...
- (转载)UI接口分层自动化测试框架设计思想
阅读本小节,需要读者具备如下前提条件: 1. 掌握一种编程语言基础,如java.python等. 2. 掌握一种单元测试框架,如java语言的testng框架.python的unittest框架. ...
- Android 自动化测试框架简介
Android常用的自动化测试工具框架: Monkey,MonkeyRunner,UIAutomator,Robotium,Appium,Monkey Talk...... 但这些工具框架都是什么呢有 ...
- 如何搭建App自动化测试框架?
目录 前言 安装Java JDK 安装Node.js 安装Appium server 第一种:使用npm工具 第二种:安装desktop版本 配置环境变量 安装Android SDK 下载SDK及安装 ...
- 手游自动化测试框架实现原理
手游自动化测试框架需要几个模块: 脚本模块:需要对常见的操作进行API封装,脚本一般选择常见的javascript,python,lua等,这个封装主要针对APP上的函数进行封装,以降低开发难度. 针 ...
- App 自动化解决方案 [开源项目] 基于 Appium 的 UI 自动化测试框架完美版
欢迎查阅Appium(Android自动化测试框架体系) Appium Appium是一个移动端的自动化框架,可用于测试原生应用,移动网页应用和混合型应用,且是跨平台的,可用于IOS和Android以 ...
- Appium自动化测试框架
Appium自动化测试框架 环境搭建 adb 构成和原理 连接 包名,界面名 文件传输 获取APP启动时间 获取手机日志 安装和卸载APP 进入到安卓手机内部的Linux系统命令行 启动和停止adb服 ...
最新文章
- Java8 中有趣酷炫的小技巧
- R语言使用survminer包生存分析及可视化(ggsurvplot)实战详解:从数据集导入、生存对象生成、ggsurvplot可视化参数配置、设置、可视化对比
- .classpath 和.project文件含义
- Apache、tomcat、Nginx常用配置合集
- 显卡测试软件毛毛虫,超龙超龙,与众不同,顶流配备,散热一流,3070Ti超龙旗舰版评测...
- 【转】Dynamics CRM:“the given key was not present in the dictionary”
- 如何查看linux 是否安装软件包,linux 查看软件包是否安装 linux查看软件包
- java解析yml文件_如何基于JAVA读取yml配置文件指定key内容
- Leetcode每日一题:973.k-closest-points-to-origin(最接近原点的K个点)
- CS224N笔记——深入GRU和LSTM
- 变桨距风力发电机液压系统设计
- 程序验证(六):纳尔逊-欧朋算法(Nelson-Oppen Procedure)
- h5做app和原生app有什么区别?
- AttributeError: module ‘torch‘ has no attribute ‘inference_mode‘
- 基于B/S模式的设备管理系统开发
- 用代码在最短时间做成事
- Java课程设计_java课设
- 总结——STM32F103C8T6通过MAX31865读取PT100电阻值
- 基于STM32的RGB调色器——STM32程序和Qt上位机全开源
- MathType 6.9中积分符号不显示该怎样解决