写给Android开发者的UI自动化测试上手指南

我们常常听到这样的问题:“为什么软件的开发者们不适合测试他们自己开发的软件?”。事实上,要回答这个问题需要明白开发者去进行测试的目的。本篇文章不会深入到自动化测试的具体细节,是对如何减少重复测试进行简单实践,让业务开发人员能够简单快速上手才是最终目的。

developer-pk-tester.jpg

开发人员测试自己所开发软件的行为就像学生在完成考试后对自己的成绩进行评估,所以可能会出现下面的问题:

  • 开发人员对其所写代码有主观认同感
  • 开发人员对软件过于乐观的心态
  • 开发人员对需求易产生偏差与混淆
  • 开发人员擅长修复但不擅长拆解
  • 开发人员缺乏对软件后续开发的展望
  • 开发人员缺乏测试经验和方法

开发者测试的目的

就如前面所说,软件开发者测试自己开发的程序好像并没多大意义,测试工程师具有很多优势条件,那作为开发者进行自动化测试的目的是什么?
其实从下面的图就能解释一切,程序员这个职业存在的意义不就是最大化利用机器,通过自动化来完成工作吗?

作为软件开发者需求很明显,当需要对自己开发的功能进行验证时,总是需要反复调试后才能提测。这不可避免的需要我们重复UI操作去覆盖测试路径,通过查看界面内容和日志输出验证问题。而UI自动化测试恰恰可以满足这一点,减少我们重复操作ui验证的步骤。


Android自动化测试介绍

关于Android自动化测试,可以去官网看一下介绍Getting Started with Testing


本篇文章不会对深入到自动化测试的细节进行描述,只是作为开发人员对如何减少重复工作量进行简单的实践,所以这里直接推荐腾讯U测社区的一篇文章:5个最佳的Android测试框架,有兴趣的童鞋可以了解一下目前主流的自动化测试框架。
Comparing-Android-Testing-Frameworks.png

解放你的双手

作为一个业务开发人员,解放双手进行功能验证性测试才是最根本的需求,所以下面介绍一下使用Espresso进行UI自动化测试的流程。

为什么选择Espresso测试框架?
很简单,Espresso是Google针对Android平台开源的一款最新的Android自动化测试框架。不用考虑跨平台、兼容性等各种问题,最贴合需求才是最好的。

UI自动化测试依据

UI自动化测试的基本思路:把自己当成用户,只关注我能看到的东西。

我们把自己作为使用程序的最终用户,要让机器模拟我的测试过程,那么就需要针对那些我能看到的东西,也就是UI组件进行验证。
比如说,作为用户并不关心某个网络请求返回值的具体数据是否正确,我关心的是能在UI上看到希望看到的结果。

基于此,做各个测试用例的一个通用的思路就是:找到某个元素,做一些操作,检查结果。这里包含了三个流程:

  • 找元素:找到UI上测试所针对的元素;
  • 做操作:给这个元素做一些操作;
  • 检查结果:这个元素做出了我期望的行为。

再直观一点,我们测试向一个EditText输入一段文字,那么整个过程就可以描述为:

  • 找元素:找到EditText组件;
  • 做操作:向EditText输入字符串;
  • 检查结果:EditText显示了我输入的字符串,验证内容是否符合。

以上三个小步骤实际上也是我们作为用户在使用一个APP的时候所遵循的流程。而我们的测试也是基本遵循这样一个流程的。下面是官方文档中给出的一个简单测试用例的代码:

@Test
public void greeterSaysHello() {
  onView(withId(R.id.name_field))
    .perform(typeText("Steve"));
  onView(withId(R.id.greet_button))
    .perform(click());
  onView(withText("Hello Steve!"))
    .check(matches(isDisplayed()));
}

代码逻辑也是典型的三步:

  1. 首先通过withId方法找到了id为name_field的EditText组件,并且调用typeText方法对其进行设置text内容为"Steve";

  2. 再通过withId方法找到id为greet_button的Button组件,掉头click方法模拟点击该按钮;

  3. 最后通过withText方法查找text内容等于"Hello Steve!"的TextView组件,调用check方法判断该组件是否匹配(matches方法)是否可见状态(isDisplayed)。

一些Espresso的主要方法

UI自动化具体实例

这里建议参照官方文档给出的步骤进行实践,示例给出自己在实践demo中配置自动化测试的基本步骤。Espresso setup instructions

1. 在gradle添加支持
在app目录下build.gradle中dependencies设置对Espresso库的编译依赖,在android.defaultConfig设置InstrumentationRunner。

// 在app目录下的build.gradle添加对Espresso的依赖
dependencies {
  androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {    
     exclude group: 'com.android.support', module: 'support-annotations'
  })
  androidTestCompile 'com.android.support.test.espresso:espresso-idling-resource:2.2.2'
  ...
}

// 在app目录下的build.gradle中设置instrumentation runner
defaultConfig {
  ...
  testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}

2. 创建Test Case文件
在Android Studio执行测试的代码类文件需要在app模块的androidTest文件夹下创建。如下图所示:

project.png

3. 编写测试用例代码
比如当我们为TestActivity创建TestActivityTest测试用例类文件成功以后:

  • 首先需要在测试用例类的类体前添加@RunWith的注解,并设置测试运行平台为AndroidJUnit4
  • 如果允许测试需要较大消耗,可以使用@LargeTest注解
  • 设置ActivityTestRule用来指明被测试的Activity,使用@Rule注解。

运行测试时用例时会自动启动到对应的Activity,并且通过ActivityTestRule的示例获取到被测试Activity的context。

  • 编写测试方法,按照前面说的“找元素,做操作, 验证结果”三个步骤编 写测试方法,使用@Test注解。

建议使用test作为方法名的开头,这样可以更好区分普通方法和测试方法


如上图所示,代码为TestActivity创建了测试用例类TestActivityTest,其中testDeciceName为其中一个测试用例方法。该方法主要是通过id查找到EditText,自动输入内容后模拟点击id为bt_get_string的button,最后验证textview显示内容是否符合。

4. 运行Test Case
在Android Studio的终端中输入gradlew connectedAndroidTest 或 gradlew cAT执行测试用例。
整体运行效果如下:

run.gif

5. 异步和延迟
有时点击一个按钮,ui操作后需要执行一个较为耗时的事情时通常会采用异步回调的方式通知显示结果,这时进行UI自动化测试的第三步验证结果的时机就不能才能同步的方式去执行,而是需要做异步回调通知执行或延迟执行。

Espresso提供了原生的异步测试支持,通过实现IdlingResource接口,复写getName()、isIdleNow()、registerIdleTranstionCallback()方法。
如图所示FuncExecuteIdlingResource:


然后在测试用例的类中注册和反注册接口:
Espresso.registerIdlingResources(idlingResource);

当方法执行完成,调用ResourceCallback.onTransitionToIdle();则会进行回调通知测试线程继续执行验证代码。

总结

一切能自动化完成的测试操作就不要浪费时间用手动完成。后续将会对单元测试进行说明,共同学习,相互提升。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,298评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,701评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,078评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,687评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,018评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,410评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,729评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,412评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,124评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,379评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,903评论 1 257
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,268评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,894评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,014评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,770评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,435评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,312评论 2 260

推荐阅读更多精彩内容