您还未登录! 登录 | 注册 | 帮助  

您的位置: 首页 > 软件测试技术 > 其他相关 > 正文

客户端自动化测试小探索

发表于:2017-01-09 作者:网络转载 来源:

  客户端测试我了解的不是很专业,在我的之前的认知里,主要由appium,macaca等构成,都是通过脚本去控制UI的各种操作,抓取元素模拟点击等等。适用场景上,确实比较适合做一些固有case的回归,但是脚本维护的成本略高,不过支持的语言够多,尤其是appium,几乎支持了所有主流语言,我试着写了一下,问题不大,就是当固有case发生变化的时候比较惨,代码很多都没法用了。虽然理论上讲固有case是不会发生变化的,但是在业务导向的团队中,不可能百分百保证固有case不发生变化,尤其还是在一个新业务的探索发展阶段。
  我是一个Android DEVER,那么我想了一个够简单的方法:通过AS2.2版本的新特性:Espresso的单元测试录制,让写UT更轻松。但是在我试过之后发现一个鸡肋的问题:录制好的脚本不更改几乎没法用。因为在大型的app上,元素的定位不是那么简单的,而录制的脚本中几乎都用 allOf 来定位元素,显然就是不行的,那么维护脚本的成本就大了,很多情况下不亚于直接用appium直接去写,所以这个方案我就放弃掉了。
  我理想中的方案是:维护脚本成本够低、写test case够简单、可读性够强、如果能Android & iOS共用那更棒,最关键的一点: 时间成本要少 。
  于是我邂逅了 Calabash 。
  Calabash上手
  我第一眼就相中它的原因就是: 它可以用一种类似自然语言的方式编写测试用例 。以往的方式都是TDD,而calabash是BDD,这让我感到很新奇,于是我做了一波尝试。
  先给大家看看我写的第一个固有case(是固有case里最简单的一个):
Feature: xxx固有用例
Scenario: 功能:首页
ThenI see"跳过"
WhenI press"跳过"
ThenI press"上海"
WhenI press viewwithid"city"
ThenI see"海外"
WhenI press"海外"
AndI press viewwithid"start_search"
WhenI enter"东京"into input field number1
ThenI press list item number1
ThenI see"东京"
WhenI press"美食"
ThenI see"美食"
ThenI go back
WhenI see"景点"
ThenI press"景点"
ThenI see"景点"
ThenI go back
ThenI press viewwithid"title_image"
ThenIwaitfor5seconds
ThenI press webviewtext"特价机票"
ThenIwaitfor5seconds
ThenI go back
ThenI go back
WhenI scroll down recyclerviewwithid"main_listview"count5
ThenI see"猜你喜欢"
ThenI press viewwithid"root_rl"number1
ThenIwaitfor10seconds
  这个没写过代码的人我相信都看得懂,其实就是用我们常规的思维模式去写测试用例。用法非常简单,如果是Mac的小伙伴那简直不要太爽,天生自带ruby,直接用gem去安装calabash就可以,这里推荐 安装calabash-android ,其实安装calabash-ios应该是类似的,大家去calabash的 github organization 中找相应平台的repo就可以,这里我以Android为例。
  安装完之后,直接用calabash gen生成目录就可以,固有的目录都会自动生成,其实主要和我们相关的就是 features 目录。
  这里面分为三部分:
  · step宏定义+自定义
  · 各种hooks的support支持
  · 自己写的测试用例,文件名用 .feature 结尾
  很简单,上面的测试case就是自己写的测试用例。到这里我突然要告诉大家:calabash只支持ruby。其实如果我不说,估计大家都考虑不到语言,因为从这个case上看,根本看不出语言。不过大家别担心,这里用到ruby的地方无非在一些自定义step和hooks,其他的目前我没发现哪里还需要用了,而且用到的ruby极其基础简单,不需要学,不知道的Google一下就完事了。
  最后用calabash run命令启动就可以,别忘了要有apk或者ipa包,这部分我就不细说了,去github看会比较详细。
  其实到这里就讲完了,接下来我会分享一下我这两天遇到的坑,也是我觉得用calabash的难点。
  疑难杂症
  难点一:定位元素
  这部分以Android为例,显然很多页面经常会出现id相同的情况,那么我们要通过各种手段定位到唯一的元素。Android极其推荐使用sdk tools目录下的 uiautomatorviewer 进行元素抓取和定位,配合肉眼和calabash console进行定位,三者结合基本上差不多,无非就是花时间多少的问题。那么webview部分calabash也是支持的,主要是通过css以及各种条件筛选进行定位,其中text内容匹配用到的最多。
  这部分只能慢慢摸索,有经验就会快了。
  在定位元素的过程中,会遇到一些宏定义的step不够用的情况,需要自己自定义step。这里给大家看我这两天自定义的几个step:
Then /^I press webview text "([^"]*)"$/do|text|
touch("android.webkit.WebView css:'a' {textContent CONTAINS[c] '#{text}'}")
end
Then /^I press view with id "([^"]*)"number (d+)$/do|id, number|
tap_when_element_exists("* id:'#{id}' index:#{number}")
end
When /^I scroll down recyclerview with id "([^"]*)"count (d+)$/do|id, count|
foriin0..Integer(count)
scroll("android.support.v7.widget.RecyclerView id:'#{id}'",:down)
end
end
  这ruby很简单把,无非就是包了一层calabash的api然后识别了一下,没啥技术含量,主要就是自己方便用,扩展一下step,这三个自定义的step我在上面的case中都有用到。

  难点二:流程控制
  Feature
  我们在上面的case中可以看到有 Feature 的标识,这是calabash的一个控制单元(我的理解),每运行一个Feature,apk都会卸载重装,保证每次都是全新无副作用的应用。
  Scenario
  这个标识是囊括在Feature中的,一个Feature可以有很多个Scenario,运行每个Scenario的时候应用只会退出再重进,不会卸载再重装。
  Hooks
  在feature/support包下,我们会看到这么几个ruby文件:
  · app_installation_hooks.rb
  · app_life_cycle_hooks.rb
  · env.rb
  · hooks.rb
  可以看到,基本上都是hook用的,我们看一个简单的 app_life_cycle_hooks.rb 理解理解:
require'calabash-android/management/adb'
require'calabash-android/operations'
Before do|scenario|
start_test_server_in_background
end
After do|scenario|
ifscenario.failed?
screenshot_embed
end
shutdown_test_server
end
  这是默认就生成好的,从字面意思上看,就是app生命周期的hook,这里可以看到,在主要用到了 Before 和 After 关键字进行操作,这个显然很容易就看懂了,于是我自己写了一个在每个step执行之后都等待2秒的hook,下面的代码写在 hooks.rb 中(这个文件默认生成是空的):
  require'calabash-android/calabash_steps'
  AfterStep do|scenario|
  sleep 2
  end
  很容易对吧?关于这部分想多了解的可以看 cucumber wiki中的Hooks部分 。
  总结
  首先,calabash是我最后唯一选中的客户端自动化固有case的方案。这里说下原因:
  · 脚本维护成本很低,就算固有case发生变化,也可以花很少的时间迅速更改脚本
  · 我们的业务固有case数量不大,操作主要涵盖的部分calabash都可以完成,编写脚本的成本低,无语言障碍
  · 可读性非常强,代码简单易懂,任何一位DEVER都可以零成本上手,有Mac的连装环境都差不多省了
  · 小范围组内使用成本低,坑有但是并不大,都可以解决,某些机型不兼容问题直接用genymotion跑就行了,最简单(主要还是固有case不复杂)
  · Android & iOS都可以使用
  · 玩起来很有意思,对于我这种懒人来说是福音
  估计还有一些高级的玩法我还不会,不过目前这些都够我写一些固有case了,目前我们组内将会对这个方案进行评估,没啥问题就组内小范围用了,如果有感兴趣的朋友欢迎一起讨论!