Android UI自动化测试技术选择与踩坑

发表于:2018-2-12 08:28

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:viseator(吴迪)    来源:viseator's blog

  写在前面
  在官方文档关于测试一节中,介绍了测试金字塔这一概念:
  即我们应该包括三个层次的测试:小型、中型、与大型:
  · 小型测试是单元测试,即可以独立运行在每个模块上的测试。它们通常模拟了每个主要的组件并且应该快速地运行。
  · 中型测试是介于大型与小型测试之间的综合测试,它们集成了数个组件并且运行在模拟器或实机上。
  · 大型测试是以模拟UI工作流方式进行的综合UI测试,它们保证了关键的终端用户的使用可以符合我们的预期。
  虽然小型测试迅速并且专注,可以让我们很快地发现错误,但它们同样是低仿真且自成一体的,这使得我们很难保证通过了所有的单元测试就可以成功地让App运行。而大型测试的优缺点恰恰与上述相反。
  由于每个层次的测试的角色各不相同,我们应该进行所有这三个层次的测试,尽管各个层次使用比例需要根据App的使用特点,通常建议三个测试的比例为1:2:7。
  UI自动化测试即属于上面说的大型测试。
  测试框架功能对比
  概览
  参考:
  https://stackoverflow.com/questions/20046021/google-espresso-or-robotium
  实际测试编写体验
  实际的编写中,主要的步骤可以总结为三步:
  1、如何定位想要操作的View
  2、如何施加想要进行操作
  3、如何判断App的行为符合我们预期
  三种框架都为我们提供了一系列方法,但细节与效果略有不同:
  Espresso
  · 白盒测试,体现在可以直接拿到显示中的View实例,拿到WebView DOM树中的Element
  · 一般场景下,区分度较为明显的View(有唯一的id tag)等,可以通过多种途径定位,较为便捷
  · 面对特殊场景:如TabLayout中的Tab时,由于它们拥有相同的类型与id,难以定位view
  · 出现多窗口情况(如dialog),可以正常处理
  · 不能触发按返回键、改变屏幕方向等操作
  UI Automator
  · 黑盒测试,体现在无法拿到具体的View,只能拿到基类(LinearLayout等),无法看到WebView的DOM树
  · 一般场景下,定位View没有差别
  · 面对特殊场景,可以通过找出所有符合条件的View再按索引找到想要的View
  · 出现多窗口情况:处理出现异常
  Robotium
  · 集合了上述框架的优点,既可以拿到显示中的View实例与WebView的DOM树
  · 对上述框架的接口进行了统一,调用比较方便
  最终框架选择
  通过上述比较,可以看到Robotium在满足我们要求的同时统一了接口,故选择Robotium作为使用的框架。
  使用过程中踩的一些大坑
  变量必须使用static
  在AndroidTest类中,期望使用一个boolean标志来判断是否已经登陆过(避免重复检查登陆状态),发现在login()方法中置标志为true后进入下一个测试时这个值仍为false,推测运行测试方法时各个方法的运行是独立的,故不使用静态变量则无法保存状态。
  等待引发的问题
  等待?
  在我们对View进行一个操作以后,框架会自动处理下一步动作触发的时机,比如点击一个Tab后,会自动等待下一个页面出现再执行下面的操作。这个等待判断的原理没有看过源码不能确定,但是实际中遇到比如WebView加载页这样等待时间较长的页面,就会触发下一个操作的执行。
  那么问题就出现了,如果想要进行这样的测试:点击打开一个文档,等待文档打开完毕以后检查标题是否是我们打开的文档,如果在文档没有加载完的时候就执行检查步骤,就会产生Element not found的错误。
  解决方法
  · 强行设置等待时间
  利用SystemClock.sleep()方法强行让测试暂停一段时间,这个方法比较暴力也不优雅,不到万不得已不要使用。
  · 使用Robotium提供的各种wait方法,通过设置退出条件来等待:
private void waitForWebView() {
assertTrue(mSolo.waitForCondition(new Condition() {
@Override
public boolean isSatisfied() {
View loading = null;
try {
loading = mSolo.getView(R.id.loading);
} catch (AssertionFailedError e) {
Log.e(TAG, e.getMessage());
}
return null == loading || View.GONE == loading.getVisibility();
}
}, DOC_LOAD_TIMEOUT));
}
  在解决上面的问题的时候就使用了上面的代码来等待WebView文档加载完毕,返回true时条件满足,退出等待,若超时,则方法返回false,assert失败表示doc加载超时。此处的判断方法是等待loading隐藏。
private void waitForActivity(Class<? extends Activity> activity) {
if (mSolo.getCurrentActivity().getClass() == activity) {
return;
}
assertTrue(mSolo.waitForActivity(activity));
}
  上述代码是为了等待activity启动,可以用于判断新的activity是否正常启动。
上文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理。
21/212>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号