关于Android的UI测试

Android 测试主要分为3个类型:

单元测试(Unit Test)

区分UI代码和功能代码在Android开发中尤其困难。因为有时Activity既有Controller的功能,又有View的功能。Robolectric是一个很优秀的Android测试框架,它提供了一个Android框架的stub,这样测试运行时实际上是在JVM上运行,而不是在Android平台(比如Robotium和Instrumentation都是在Android平台运行测试),从而提高了速度。另外请参考Gradle 对 Unit tests的支持

封闭UI测试 (Hermetic UI Test)

这个测试方法使得测试不需要外部依赖和网络请求。这样做的主要目的是提高测试速度,减少测试时的外部影响,毕竟网络调用是相对很慢的。Espresso可以用来模拟用户的UI操作。

Monkey Test

Monkey Test 就好像一只猴子在测试app一样,没有任何规律的在你的app上胡按。计算机运行monkey test的时候,每秒钟能做出几千个UI动作(可以配置这个频率),比如点击和拖拽。所以这个测试可以算是一个压力测试,用来检测ANR


Google+ 团队总结了一些 UI 测试时的经验和策略。

策略1: 不要使用 End-to-end 测试作为UI测试

先看一些定义:UI 测试 是为了确保对于用户的UI动作,app能返回正确的UI输出。End-to-end测试(E2E test) 是通过客户端和后台服务器的交互测试整个系统。下面这个图在展示了测试步骤:

通常做UI测试,你需要后台服务器,所以可能产生网络调用。所以UI测试和E2E测试很像。但是在E2E测试中会遇到很多困难:

  • 测试速度缓慢
  • 网络请求会失败
  • 难以Debug

下面看看如何解决这些问题。

策略2:使用伪服务器做封闭UI测试

这个策略中,你可以通过假的后台服务器来避免网络请求,以及其他外部依赖。技术上,你就需要在app本地提供返回数据了。有很多办法可以做到,比如手动做一次网络请求,把response保存下来,在测试的时候重复这个response。这样你就做了一个封闭在本地的伪服务器

当你有了这个伪服务器,你还需要给这个伪服务器写测试。于是这是,你的E2E测试就分为了服务器测试,客户端测试和集成测试。

现在这样的解决方案,你需要自己维护伪服务器,本地数据库和tests了。

下面这是E2E 测试的示例图:

这是使用了伪服务器的封闭UI测试

其区别在于:Frontend Server的几个数据源变了。由原来的真实后端,变成了封闭服务器,或者是mock服务器。这个在测试调用网络API的时候非常有用。

策略3:使用Dependency Injection

Dependency Injection(依赖注入)可以帮助生成测试数据。我推荐选择使用dagger作为依赖注入框架。

依赖注入在UI test和unit test都中都可以用于生成假数据。在instrumentation test框架中,测试用的apk文件和测试时运行的app,是在同一个进程下面,所以测试代码可以调用app代码。你还可以覆盖app的classpath,通过这种方式注入假数据。比如你可以用依赖注入来伪造一个网络连接的实现,调用这个网络连接的时候就可以提供假数据。

策略4:把app分为小的libraries

这个方法可以更好地模块化你的app。你的app被分为更小的类库之后,你可以为这些类库添加他们自己的UI依赖或gradle库依赖。

当你有了自己的库,并提供依赖注入的支持,那么你可以为各个库写测试app。最后,可以写集成测试来确保类库直接的合作正确。

比如我们有一个登陆功能的库,那么我可以写一个测试app只为这个登陆功能库:

总结:

  1. 不要用E2E测试来代替UI测试。更好的做法是用单元测试 + 集成测试 + UI测试。
  2. 使用封闭测试策略
  3. 使用依赖注入
  4. 把app分为不同的小组件小类库,并分别写测试,然后再写集成测试来确保各组件之间的交互正确。
  5. 模块化 UI 测试已经被证明了比E2E测试快,并且十分稳定。这样的测试又能极大的提高开发效率。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏北京马哥教育

秒懂!四步16点高效搞定高性能web服务器nginx

Nginx(读音engine x)服务器由于性能优秀稳定、配置简单以及跨平台,被越来越多的公司和个人所采用,现已成为市场份额继Apache之后的第二大Web服务...

18930
来自专栏张戈的专栏

解决Linux下MySQL启动错误Starting MySQL.Manager of pid-file quit without updating file.[FAILED]

上午刚装完 MySQL,启动时报如下错误: Starting MySQL.Manager of pid-file quit without updating f...

41250
来自专栏JavaEdge

操作系统之进程管理一、进程二、进程状态及状态转换三、进程队列四、进程控制五、深入理解六、线程七、死锁二、资源分配图(RAG:Resource Allocation Graph)三、死锁预防四、死锁避免

695100
来自专栏北京马哥教育

出了Linux 故障找不到方法?看大牛简单、朴实的解决思路

本文由马哥教育Linux云计算面授班23期学员推荐,转载自互联网,作者为Lis,Linux资深技术专家,内容略经小编改编和加工,观点跟作者无关,最后感谢作者的辛...

47660
来自专栏北京马哥教育

Redis集群及管理讲解

一、为什么要弄redis集群 集群技术是构建高性能网站架构的重要手段,试想在网站承受高并发访问压力的同时,还需要从海量数据中查询出满足条件的数据,并快速响应,我...

45370
来自专栏容器云生态

根据红帽RHEL7官方文档对centos7进行技术剖析(二)

第一章 使用红帽kickstart,自动化安装rhel。 http://pan.baidu.com/s/1qWqfXlq    文档下载地址。 第二章: 控制对...

40170
来自专栏Java职业技术分享

java框架之Spring 核心框架体系结构

很多人都在用spring开发java项目,但是配置maven依赖的时候并不能明确要配置哪些spring的jar,经常是胡乱添加一堆,编译或运行报错就继续配置ja...

11500
来自专栏玄魂工作室

Python黑帽编程1.3 Python运行时与包管理工具

Python黑帽编程1.3 Python运行时与包管理工具 0.1 本系列教程说明 本系列教程,采用的大纲母本为《Understanding Network...

391150
来自专栏CDA数据分析师

工具 | 当python爬虫遇到10060错误

相信做过网站爬虫工作的同学都知道,python的urllib2用起来很方便,使用以下几行代码就可以轻松拿到某个网站的源码: ? 最后通过一定的正则匹配,解析返回...

27290
来自专栏云计算教程系列

如何在Ubuntu 14.04上安装Cassandra并运行单节点集群

Cassandra或Apache Cassandra是一个高度可扩展的开源NoSQL数据库系统,在多节点设置上实现了出色的性能。

29730

扫码关注云+社区

领取腾讯云代金券