51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 2380|回复: 1
打印 上一主题 下一主题

[Appium] appium 自动遍历的参考代码

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2017-6-29 14:22:58 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
背景上次支付宝沙龙分享了基于appium的自动遍历小工具,  有些朋友感兴趣, 想看下代码,
为了给大家一个参考, 我这里贴部分的关键算法代码给大家吧
这份代码写的很挫, 功能也很简单, 只是个演示demo, 是为了证明appium can do IT.
我计划用Java重构, 这个只当是参考吧
部分代码参考
  1. def capabilities
  2.     {
  3.         'browserName' => '',
  4.         'device' => 'android',
  5.         'version' => '4.1',
  6.         'app-activity'=> 'com.taobao.tao.Welcome',
  7.         'app-package'=> 'com.taobao.taobao'
  8.         #'app-activity'=> '.activity.MainActivity',
  9.         #'app-package'=> 'com.sankuai.meituan'
  10.     }
  11. end

  12. def setup
  13.     server_url = 'http://127.0.0.1:4723/wd/hub'
  14.     @driver = Selenium::WebDriver.for(:remote, :desired_capabilities => capabilities, :url => server_url)
  15.     @driver.manage.timeouts.implicit_wait = 30 # seconds
  16.     puts 'sleep 20'
  17.     sleep 20
  18.     @driver
  19. end
  20. def config()
  21.     @config={}
  22.     @config['blacklist']=['立即抢购', '美团承诺 团购无忧', '退款']
  23. end

  24. def refresh()
  25.     root=[]
  26.     el_array=@driver.find_elements(:xpath, "//text[@clickable=true]")
  27.     #如果点击没有发生变化, 就跳过
  28.     if el_array.size==@list.size
  29.         return @list
  30.     end
  31.     el_array.each do |node|
  32.         begin
  33.             text=node.text
  34.             location=node.location
  35.             is_skip=false
  36.             next if text.strip==''
  37.             next if text.size<2
  38.             @config['blacklist'].each do |keyword|
  39.                 if text.index(keyword)
  40.                     is_skip=true
  41.                     break
  42.                 end
  43.             end
  44.             next if is_skip
  45.             current={}
  46.             current['click']=false
  47.             #位置相差不大 也认为是相同
  48.             current['sign']=text+'|'+location.x.to_s[0..1]
  49.             current['text']=text
  50.             current['object']=node
  51.             root << current
  52.         rescue Exception=>e
  53.             puts e.message
  54.         end
  55.     end
  56.     root
  57. end
  58. def find_return_root(el)
  59.     current=nil
  60.     @nodes.each do |node|
  61.         if node.content['sign']==el['sign']
  62.             current=node
  63.             break
  64.         end
  65.     end
  66.     current=current.parent if current
  67.     return(current)
  68. end
  69. def travel()
  70.     @list||=[]
  71.     @nodes ||= Tree::TreeNode.new("ROOT", {})
  72.     @current||=@nodes
  73.     @index||=0
  74.     @index+=1
  75.     @list=refresh()
  76.     has_new=false
  77.     return_root=nil
  78.     @list.each do |el|
  79.         #判断是否曾经出现过
  80.         return_root=find_return_root(el)
  81.         if return_root==nil
  82.             has_new=true
  83.             #如果是新元素, 就添加到tree中
  84.             @current << Tree::TreeNode.new(el['sign'], el)
  85.         end
  86.     end
  87.     #如果没有新元素, 代表回到某个父节点
  88.     if has_new==false
  89.         @current=return_root
  90.     end
  91.     save()
  92.     if @current.level>7
  93.         @driver.navigate.back
  94.         travel()
  95.     end

  96.     #从未被点击的地方点击
  97.     current=nil
  98.     @current.children.each do |child|
  99.         if child.content['click']==false
  100.             current=child   
  101.             @list.each do |node|
  102.                 if node['sign']==current.content['sign']
  103.                     current.content['click']=true
  104.                     @current=current
  105.                     node['object'].click
  106.                     sleep 3
  107.                     travel()
  108.                     break
  109.                 end
  110.             end
  111.             break               
  112.         end
  113.     end
  114.     if current==nil
  115.         @driver.navigate.back
  116.         travel()
  117.     end
  118. end
复制代码
运行结果因为这次采用的是uiautomator, 代码也优化, 所以执行时间很长
跑十几分钟, 手机就因为锁屏失败, 所以针对淘宝app, 我一直没跑全过, 生成的思维导图只是淘宝部分栏目的浅层结构图 想跑全的话, 就自己修改手机, 或者用虚拟机吧
如下是生成的结果:


计划我接下来, 我在做上次分享的ppt最后一页的事情, 我想基于这个搞个在线服务. 有实力感兴趣的同学可以报名参加.
主要是为第三方的企业提供app遍历和附加服务. 一个实验性的技术项目.
目标
  • 优化速度
  • 优化算法, 解决回环
  • 自动生成appium的自动化代码
  • 支持规则
  • 从ruby转到java上去实现
  • 做个服务网站
  • 支持dom diff和灰度对比

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏
回复

使用道具 举报

该用户从未签到

2#
 楼主| 发表于 2017-6-29 14:46:11 | 只看该作者
重要的是算法,点击这个没什么, 点击是入口, 现在只是纯点击, 以后加了规则, 就可以支持更多操作了, 比如滑动, 自动输入. 目前还得加上回环算法才算靠谱 所以除了怕嘲笑, 我也觉得没什么可保留的 , 就贴出来给大家参考下.

大家有好的思路, 也不放show下, 欢迎指教
另外, 这种纯黑盒的方式也不太好, 通过插桩可以获得更多的建模数据. 也是个缺点, 还需要继续想办法. 我倒是挺喜欢百度Cafe的做法.使用hook来解决
回复 支持 反对

使用道具 举报

本版积分规则

关闭

站长推荐上一条 /1 下一条

小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

GMT+8, 2024-9-28 07:24 , Processed in 0.066840 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2024 Comsenz Inc.

快速回复 返回顶部 返回列表