51Testing软件测试论坛

标题: Android自动化基于UIAutomator的实现及代码生成 [打印本页]

作者: 小小糖    时间: 2018-4-23 13:34
标题: Android自动化基于UIAutomator的实现及代码生成
Android UI自动化测试这块一直是google忽略或者技术薄弱的地方,以至于他没有提供一套完整的自动化测试
框架。国内公司做UI自动化测试一般都借助于第三方测试框架如robotium,淘宝测试(TMTS),Robolectric
等。但这些测试框架或多或少都存在一些跨应用,事件等待等不足,无法满足UI自动化的所有要求。

  Android4.0之后,google仿照微软UIAutomation引入了UIAutomator测试框架,虽然是刚刚推出,各个细
节还比较粗糙,但毕竟是Android原生的测试技术,再加上这套东西微软已经使用了多年,已经是很成熟了,
所以相对第三方测试框架还是比较有优势的。接触到uiautomator之后我第一个想法就是可以仿照微软POM/L
FM将测试代码写得更加优雅。整个思路就是一个分层设计,控件的定义,和控件的操作分为两层,而测试方
法调用底下两层,做为第三层。这么设计的好处是明显的:较少代码编写量,并可以在团队写代码中更加容
易保持代码风格;代码易维护,改动任何一层代码对其他层影响较小;可以针对Android系统泛滥的弊端针对
不同的android系统或手机,生成一种通用库,这样很容易做手机多机适配运行;另外针对POM层,只要代码
格式设计完成,可以适当扩展Uiautomatorviewer以自动生成代码(我扩展了右边栏的TreeView,增加了双击
自动生成代码保存到剪切板里,这样想要生成哪个控件的定义代码,双击,粘贴一下就行了,非常方便)设
计图如下:


[attach]114219[/attach]




最终代码是这个样子的:



复制代码
  1. public void testSendPicByLocal() {
  2.     this.lfm.openApp();
  3.     this.lfm.goTabMessagesByXY();

  4.         Uia.hand.clickAndWaitForNewWindow(
  5.                 this.pom.messages.relativeLayoutChatSession(1), "点击回话列表中第一个");
  6.         if (this.pom.chat.buttonHoldToRecord().exists()) {
  7.             Uia.hand.click(this.pom.chat.buttonCancelRecord(), "如果录音按钮存在,则点击关闭");
  8.         }

  9.         Uia.hand.click(this.pom.chat.imageButtonPlus(), "点击+");

  10.         for (int loop = 0; loop < 500; loop++) {
  11.             if (!this.pom.chat.textViewPhotoWhenPlusClicked().exists()) {
  12.                 Uia.hand.click(this.pom.chat.imageButtonPlus(),
  13.                         "加号区域已经收回,点击+再次弹出");
  14.             }

  15.             Uia.hand.click(this.pom.chat.textViewPhotoWhenPlusClicked(),
  16.                     "点击Photo");
  17.             this.lib.lfm.photo.getPhotoFromAlbum(); // 调用公共类库拍照方法,可根据不同手机实例化出不同对象
  18.             Uia.hand.click(this.pom.chat.imageViewImageSelected(),
  19.                     "点击右下角对号,确认发送");
  20.         }
  21.     }
复制代码

复制代码


那么针对uiautomator的代码自动生成或者说录制怎么做呢?

  有一个取巧的办法可以通过UiAutomator将页面所有的控件保存到xml中,然后解析xml,生成POM层的代
码,虽然只能简单生成POM层代码,但这至少也减少了百分之三十的编码量。

  上述扩展uiautomatorviewer的方式比这种更加方便一点。

  其实可以考虑使用AccessibilityService,监控用户输入,在onAccessibilityEvent(AccessibilityEvent)方法中
解析Event,根据Event类型和其携带的控件属性生成基于UIAutomator的测试代码,然后将测试代码拉出手
机,放入事先建好的工程模板中编译即可。

EventSource eventSource = praser.prase(event.toString()); // 设置筛选条件,选择特定事件生成代码。 if
(Config.MatchedEvents.contains(eventSource.getEventType())) { generator.generateCode(template.getMe
thodStepSteam(eventSource)); }



这里不给出具体实现了。

这里提一下Uiautomator源码的一个小bug,这个bug在最新版的4.2.2里已经修复,但你用uiautomator的时候还得注意一下:

uiautomator4.2.2版本一下引入uiautomator.jar时,凡是继承自uicollection的方法UiObjectNotFoundException都没有被抛出,google的工程师自己catch到给打印出来了,所以你的测试代码没办法catch这个异常,

发现这个bug是在scroll一个feedlist时调用scrollforward的方法,结果总是有异常UiObjectNotFoundException,于是想测试代码catch代码段重新scrollforward一下,结果发现这个异常没有抛出,去官网看wiki文档,确实抛出有写这个方法会抛出这个异常,也去翻看了uiautomator源码,确认了,可就是找不到原因,后来灵光一闪,才确认了引入了4.1.2的uiautomator.jar包,这个包里源码给处理了,google的工程师也会犯这么低级的错误。


作者: 梦想家    时间: 2018-5-9 10:01





欢迎光临 51Testing软件测试论坛 (http://bbs.51testing.com/) Powered by Discuz! X3.2