打造企业级移动测试云平台

背景

移动技术发展到现阶段,原生、混合式技术发展的足够成熟,可以无缝融合。而随着移动技术的发展和革新,移动领域的测试技术和实践也有了一定发展:工具不再像早期一样几家独大,选择性越来越多;从浅尝辄止的实验阶段到真实项目中的自动化测试落地。这些实践在一定程度上提升了测试反馈效率,在迭代交付的过程中出色的完成了质量保证的工作,但在相对漫长的实践过程中,我们依然可以总结一些痛点:

1、移动自动化测试的执行效率远不及Web应用

有过Web自动化测试经验的同学对于Selenium肯定不会陌生,Web端的并发测试使得测试在有限资源的情况下按照我们的期望并发执行。而且由于keychain等问题,很难在测试用例之间做到互不影响、对于测试环境的清理和准备也有很大难度。

2、很难全面覆盖繁杂的测试设备

Web自动化测试关注的测试环境相对单纯,针对不同项目、产品和市场,无非是对不同的浏览器和操作系统有不同程度的支持。而对于不同浏览器也有不同的driver来支持。而在移动测试中,很难做到对众多厂商和不同操作系统设备进行模拟。

3、移动自动化框架很难支持到回归测试颗粒度

在移动端(以iOS为例),受限于Apple的机制,大部分框架很难覆盖到与iOS系统/第三方App交互的场景,例如系统通知跳转、实时通讯应用信息发送等场景。而若无法覆盖核心功能,那么自动化测试的落地实则是在给自己和团队挖坑,得不偿失。

这些问题在随着WebDriverAgent的成熟以及XCode 9的新特性 —— Multiple concurrent simulators的出现,得到了极大程度的解决,我们可以像对Web应用一样,对移动端应用在不同的simulator上并发执行测试用例,极大提升了测试反馈效率。而且,测试人员不再受限从而可以编写覆盖率更高的测试用例。

除了普适性问题之外企业对移动测试方案潜在需求?

在项目的具体实施过程中,除了我们经常被这些普遍存在的细节问题困扰之外,企业或组织级客户已经对移动端自动化测试提出了更高的要求。在一次机会给客户讲解移动端自动化测试趋势时发现,新的框架的确会使客户眼前一亮,但是,在实践上的优势无非是你比其他人先研究了什么,这样的领先微乎其微,在交流过程中观察到客户更大的痛点是:

如何同时覆盖到更多物理设备?如何更好的构建和重用基础设施?如何跨地域高效使用测试资源?

带着这几个问题,我们对比了一些现有的可用方案,例如AWS device farm。Device farm是针对移动App提供的测试服务,用户可以对在AWS托管的基于iOS和Android物理设备测试原生和混合应用。用户既可以使用各种测试框架来做自动化测试,也可以远程访问设备进行应用程序的测试和调试。

但是该解决方案也是有一定局限性的,当测试运行期间同时执行测试的设备最大只有五个,而运行测试的时间也被限制到60分钟。当然上述的限制可以根据需要适当的放松,但是企业和用户不得不承担价值不菲成本。

与AWS device farm类似,SauceLabs和Xamarin也提供类似的平台,那SauceLabs的服务举例,如果想使用无限运行时间,支持24个并发运行设备,模拟器用户需要每月承担3576刀,而如果想使用真实设备进行测试,大概需要每月花费7200刀。这种昂贵的成本对于企业很难承受,而且重要的是这种资源是无法复制,企业不得不持续为云服务支付高昂的费用。

安全性也是企业需要考虑的问题,用户不得不在云测试平台上传自己的IPA或APK。我们当然可以信赖AWS的安全机制。一些对安全性要求较高的企业来说,更想规避这样的风险。

打造私有移动真机测试平台

通过分析,对于客户的需求大概涵盖几点:真实设备、并发、成本、安全、可重用。鉴于这些需求,我们把目标进行拆分:

1.设备管理——服务发现与注册

在该实例中我们使用WebDriverAgent作为测试框架,需要运行在每一个物理设备上,我们可以把这些物理设备当作Agent集群。这些集群设备就是我们运行WebDriverAgent的服务终端,我们可以通过很简单的程序让WebDriverAgent自动在设备上运行。通过服务发现与注册机制,把WebDriverAgent服务注册在通过Ansible管理的Proxy上。而服务发现与注册不单单解决了复杂的设备管理,而且可以解决分布式团队合作时设备跨地域有效利用的问题。

2.平台数据可视化

对于一个测试平台来说,如何把所有可用的服务(机器)、服务状态、自动重启和crash报告等数据可视化给企业终端用户,是极为重要的。那老牌Apache zookeeper来说,提供了友好的服务可视化管理功能并且可以根据用户需求进行二次开发。重要的是,这些底层基础设施服务可以在之后的任何一个移动测试项目中被重用。

3.自动化测试运行和报告生成

自动化测试平台虽然提供了强大的服务(设备)管理、服务可视化等功能。而自动化测试的核心需求依然是如何保障测试的独立性、稳定性、易维护性、重用性和覆盖率。通过WebDriverAgent跨语言测试框架,我们可以像架构Web自动化测试一样来开发针对移动端的测试工程。但需要注意的是移动测试不同的是真实物理设备,而不是计算机的某个进程。另外,如何接触测试场景的相互依赖、保证测试间的独立性,以及如何清理测试环境,需要大家在进行移动端架构的时候事先考虑。

这样一来,我们如果可以解决这三个问题,就可以不受昂贵的成本限制,为企业量身定做适合自己的业务规模的移动测试私有云了,不但为企业和组织机构构建了大型测试服务平台,同时也解决了之前提到的普适性问题。

总结

随着DevOps的发展,软件工程的开发、部署、上线、应急预案等都被自动化监控和处理。如果我们依然停留在“成熟”的解决方案而缺少思考,那么留给QA/测试人员的发展空间越来越少。

我们需要通过对测试技术细节的不断归纳、对比和练习,抓住领域发展趋势和真正的客户诉求,结合其他非测试技术,帮助自己在测试技能上有所突破,同时帮助自己提升构思和落地解决方案的能力。


更多精彩洞见,请关注微信公众号:思特沃克

Share

复杂业务场景下如何进行iOS端自动化测试

去年写了一篇关于《容器化时代对测试的机遇》的文章,提到了一些分布式自动化测试和容器化技术结合的架构设想。但是目前来说,分布式运行并不是难点,亟需解决的问题是针对特殊平台和复杂场景下的测试,例如复杂业务场景下iOS平台的自动化测试。

移动应用特点是简单易用和UI简洁,以便用户在移动端完成一件事的路径尽可能短。所以一般情况下,我们遇到的iOS APP场景相对于Web应用要简单一些。所以一般情况下iOS自动化测试并不会遇见复杂场景,测试反馈时间短,效率相对较高。对运行环境来说,只需要相应版本macOS系统以及Xcode环境即可。

但是,对于大型企业的移动应用,例如电商平台、共享出行平台等,牵扯到的主要几个问题:

1. 大规模的测试用例导致测试反馈时间太长

说到这个问题,就要说到现在主流的移动端自动化测试框架AppiumCalabash。我所经历过的大部分项目,无外乎使用其一。

但在Xcode 7之后,iOS Simulator变得越来越慢(做iOS的同学们应该都有体会),更不幸的是,在iOS 10、Xcode 8之后,Apple弃用了UIAutomation,导致大量高效、常用的API无法使用。

并且迄今为止,Appium没有针对iOS 10平台发布一个正式版本的lib和APP,这就导致一些用户无法使用inspector定位元素(使用ARC的用户除外),虽然官方建议不要使XPath进行元素定位,但有的时候我们不得不这么做。最大杀器是iOS自动化受到Apple的单例限制(一台物理主机同一时间有且仅有一个Instrument)。

这些种种最终导致了iOS自动化测试时间太长,更不用谈及多种iOS设备的兼容性问题了,自动化实现过程成本过高,令大部分组织和团队食之无味、弃之可惜。

2. 复杂场景无法在一台机器上进行测试

对于复杂场景的应用来说,我们很难通过现有框架同时在一台物理机上控制多个不同的模拟器,也无法随意的切换到系统级控件去查看APP触发的通知等等。你可以通过一些合法途径使用虚拟化做iOS端的并发测试(切记合法途径)。

但这样还是逃不掉物理机庞大的开销以及虚拟机的性能损耗问题,抛开这个问题不讲,单从复杂场景来说,例如出行平台,你需要一台机器作为乘客发布订单,还需要多个拥有不同地址定位的车主来测试订单推送优先级等。对于这种复杂场景来说Appium控制起来就很难了。

3. 测试场景需要切换不同APP

如今很多的APP功能不单单是在应用本身,可能还需要跟系统应用以及其他应用进行交互,例如用户在被测APP中执行某个操作之后,需要检查notification,或者在测试的过程中需要切换无网络环境,从而测试APP的不同行为。

想到这些复杂场景和各种坑之后,估计打算做iOS测试的同学心里开始打退堂鼓了。下面我们来一步步逐一解决这些问题:

问题一:解决Instrument单例的限制

对于这个问题困扰了很久,那业界领先的互联网公司又是怎么做的呢?有一次看到Uber的Showcase,在一台机器上启动了5、6台模拟器,用不同类型的账号登录(乘客、车主)每个模拟器做不同的行为。由于是在物理机上的对iOS模拟器的操作,速度和性能都得到了很好的保证。他们是怎么解决Instrument的限制呢?

我们可以通过使用Apple私有API,同时操作不同型号的模拟器,对多个不同的Simulator进行批量化操作,例如启动、重置、安装、运行等操作:

问题二:解决复杂场景下控制不同iOS模拟器的不同行为

xcodebuild命令使我们可以把WebDriverAgent运行在我们想要的设备上,但如果使用Apple的命令,还是只能在单个设备上安装运行,之前运行的多台设备都会自动关掉,而只会保留命令中的destination,默认启动8100端口去检测这台设备:

如果这样的话,那我们之前做的所有工作不就没有任何意义了吗?别急,我们已然可以通过Apple提供的资源,对不同的设备启动不同的进程端口进行监听:

这时我们可以通过curl命令launch我们需要的进行测试的APP,可以轻而易举的拿到当前运行APP的session:

curl -X POST '-H "Content-Type: application/json"' -d "{\"desiredCapabilities\":{\"bundleId\":\"com.apple.Preferences\"}}" http://localhost:8101/session

response:
{
  "value" : {
    "sessionId" : "94A6580F-1F0F-4411-AC64-3E2525BBA5E1",
    "capabilities" : {
      "device" : "iphone",
      "browserName" : "Settings",
      "sdkVersion" : "10.1",
      "CFBundleIdentifier" : "com.apple.Preferences"
    }
  },
  "sessionId" : "94A6580F-1F0F-4411-AC64-3E2525BBA5E1",
  "status" : 0
}

同时,对于不同的设备,我们可以通过HTTP server启动inspector来帮助我们进行APP中的元素定位,即使是系统应用:

问题三:解决不同测试场景需要APP的切换

有了第二个问题的解决方案,只要执行相似的curl命令,就可以拿到不同的APP以及不同的sessionId.

是时候放弃Appium了?

通过Uber的Octopus框架以及Appium正在使用的WebDriverAgent, 不难发现此方案的推广速度以及乐观的前景。我们可以使用不同curl命令对不同的Simulator以及APP进行query、tap、typing以及touch id等操作,这与Appium提供的那些我们最常使用的API的等价的,并且由于不需要先去调Appium API 而直接去通过WebDriverAgent与元素进行交互,使得测试执行速度上有不同程度的提高,又由于自身强大的控制力以及灵活性,使其可以轻松进行并发操作和复杂业务场景支持,我们只需要把不同的curl命令进行封装,结合各自APP的业务场景便可以轻松完成。

带来的成本?

可以说大部分团队没有引入移动端自动化的原因,最主要的无外乎编写成本高,UI变化快。个人认为这个方案带来的价值比其带来的成本要大得多。不再需要QA再去学习新的语言来编写脚本,所有与APP元素的交互都可通过HTTP请求来完成,元素信息通过易读的JSON来呈现。我们可以通过任何语言和框架用编写后端自动化测试的方式完成iOS的自动化测试。

下面通过测试ThoughtWorks的StartKit做一个简单的登录页面的测试Demo,并且我们已经在超过三个项目中使用过该测试方案。

总结:

由于项目因素,我们实践的场景会相对受限,长时间如此可能会影响我们解决问题的思路,我们应该不时的跳出自己工作之外去思考,把简单的事情做的复杂,这样才可以在碰到复杂问题的时候,做的简单。


更多精彩洞见,请关注微信公众号:思特沃克

Share

QA,从1.0到4.0

迄今为止,敏捷开发方法在各个公司都有了长足的发展,曾经的测试人员慢慢的在向QA职能过渡,但依然很多人不了解QA和测试的区别是什么。

敏捷实践不断地演化过程,使项目中各个角色不断弱化,同时,对每个成员的要求也越来越高。“全功能团队”的提出,不单单是对开发的要求,对QA来说,想要在快速变革中具备竞争力,就现在所具备的技能来说,还是远远不够的。

简单聊聊我所经历的“QA发展史”

1-qa4-0

(图片来自ThoughtWorks UX设计师 高媛媛)

QA 1.0 —— 机械化流水线作业

在我实习的那年,软件领域还很少提及QA,伴随着瀑布模型的兴起、软件工程规模的不断扩大以及市场对软件质量要求的提高,催生出了“测试工程师”这样一个角色。那时他们的职能很单一,每天的工作就是在各种测试环境中按照详细设计的文档,编写测试用例,并逐条测试,检查功能完整性,发现软件中可能出现的功能缺陷,并进行追踪。

这个时期是软件测试的原始时期,对测试人员的技能要求不高,只要对文档理解透彻,做事细心,是很容易胜任的。此时的产出和交付物可度量,虽然如此,测试工程师只是执行者,能力和价值都无法最大化,却被每天重复的工作所累。

QA 2.0 —— 过程化带来不同的工作内容和价值体现

我毕业的时候,开始接触敏捷方法,团队规模从百人变成了仅有十人左右,信息平等取代了逐级传递,分散的信息源( 客户的每一封邮件和每一句对话都可能是我们将要做的功能 )取代了几十甚至百页的文档,测试不再仅是提出软件缺陷和编写、执行测试用例,而是成为了团队的数据库和字典。

2-dictionary

当用户提出一个功能的时候,测试人员可以快速的进行需求分析,回顾并确定是否与此前的功能有冲突。当开发人员对某一块业务不了解的时候,测试人员也可以组织会议进行阐明。由于对业务和客户的深入了解,测试人员可以为客户提出建设性意见和功能,有时也会是做出决策的人。

高效、频繁的沟通,大大提升了QA的软技能。此时的测试人员已经过程化,对软件质量的理解,从“发现缺陷”提升到“对软件开发过程的质量控制和风险预估”,我们定义这样的测试工程师为QA。

QA 3.0 —— 自动化技能提高生产力

随着工程实践的日益成熟,QA的角色和工作日益复杂,这使得他们在大量重复、繁杂的工作与更有意义的角色之间频繁切换,这对软件质量也产生了一定影响。

3-transform

QA从开始的手工测试、探索性测试等手段,逐渐发展成为可以利用工具和程序对测试进行快速的回归,对软件性能进行有效监控,无论是前端还是后端、web应用还是移动平台。这使得自己从繁杂的重复性工作中解脱出来,去做更有意义的事情。他们通过项目的积累以及团队成员的帮助,对测试技术有了一定的认识。

QA 4.0 —— 角色向多技能、服务化转型

记得几年前,前公司领导对我说,“不管开发换了什么技术栈,你做的自动化框架都可以继续使用,对你来说没有任何影响。”当时我也赞同,认为框架已经足够好,可以适用于任何场景和业务。

从某个角度来说确实是这样, 测试相对于开发技术的指数级发展,平稳的太多。不论是在互联网还是移动互联网时代,缓慢的发展速度给了我们一种太平盛世的错觉,似乎我们掌握的技术足够坐吃几年。

来到ThoughtWorks之后,我发现了类似的事情,不论是在交付还是咨询的过程中,会有意无意中推一些我们认为的最佳实践,当遭到客户质疑和challenge的时候,我们似乎很沮丧。

在北京出差的日子,有幸做了一次咨询,虽然只有几天,让我学到一件事,我们认为的最佳实践和方法,并不完全适应于所有场合,尤其是在我们这样的咨询公司,对客户实施怎样的方案,取决于客户的领域、产品/项目特性、用户群、技术水平、政治文化、技术栈以及目标和期望等等。

4-balance

如果对于“最佳实践”过于坚持,也会影响客户关系和咨询效果。之后咨询同事讲的几个故事也似乎让我认识到,虽然我们对现在的工作和技能足够的熟练,但依然不够。

我们似乎还需要具备以下的能力:

1.尝试用不同的方法写“茴”

经验丰富的QA对于测试技术中的关键点都烂熟于心, 除了我们正在使用的方案和技术,尝试用不同的语言、框架去实现关键点和难点。这样的好处在于,我们可以通过深入的学习和使用,对流行方法、过程和框架进行比较,了解各自的优势和劣势,不但可以增强自身的技能,当面对不同客户的时候,也可以给出客观的分析,为客户提供精准服务,同时如果可以对客户现有的技术和方案、流程和方法提供有价值的意见,也可以提高在客户现场的生存率,轻松俘获客户。

2.If you cannot test it, dev it.

软件过程中,QA可以在需求分析和定义阶段介入,为项目提供不可估量的价值,但另一方面,QA技能实践(此处指Tech)是一个相对受限的领域,我们很难绕过未实现的代码和工程去做更多的事情。

你可能会说,“没有做过mobile的项目,如何去学习移动端的测试技能?”如果恰好你对行业的发展具有前瞻性和敏感度,例如你可能认为IoT和VR是一个趋势,你却没有机会去这样的项目中做QA。

那么我们是不是可以像开发一样,提升自己的学习能力和适应力,保持对技术的敏感度和热忱,了解不同技术领域,对该领域的开发、测试、构建和集成部署都有一定的了解?所以,如果你想比其他人走的快那么一点,go dev!

5-golf

3.真正的全功能

QA的领域虽然相对受限,但幸运的是角色相对不受限。在日常的开发过程和项目积累过程中,不但能对业务有深刻的理解、对用户行为有独到的见解,而且对技术也有一定的认识。

在需求分析过程中,QA总是可以从技术和业务结合的角度扮演好一个BA的角色,成为一个优秀的PM,甚至我们可以在客户提出一些需求的时候尝试着从一个UX的角度去设计原型,如果具备前端的能力,也可以自己去Dev、UI,不断拓展自己的技能领域,使自己成为真正的全功能。

总结

真正的全功能,并不是单纯意义上让QA去做Dev,而是最大程度弱化角色的概念,逐步强调和培养技能多元化。如何把对需求的理解能力强化为业务分析能力,把质量控制能力强化为项目管理能力。强化自身的优势,跳出自己的舒适区,使自己能够轻松胜任。这样我们才不会在看到去QA和QA消亡之类的观点后,无所适从。

 


你想看到的洞见,都在这里

wechat

Share

容器化时代对测试的机遇

对于工作在复杂系统上的测试工程师,我们眼前浮现的都是这些人的屏幕上开着N个远程桌面,N个虚拟机,他们在每个交付迭代周期内都疲于奔命,顾此失彼地应付着各种不同的环境、浏览器和操作系统。在我曾经工作过的A公司和D公司,测试和开发人员的比例几乎是1:1甚至更高。

过去的几年里,测试的工作似乎变得完善和高效,成熟的敏捷实践使很多测试工作得以自动化,这无疑降低了企业成本,也使得测试本身变得更有趣,人们有时间去做一些创造性的工作,而把重复的、了无生趣的工作交给了机器和脚本。

但是,虽然我们做了很多改变,但就目前的情况而言,依然不是很乐观,我们还是会碰到诸如此类的问题:“我的环境没发现这个defect,你来帮我重现一下”,当我们信心满满去尝试重现的时候,却可能再也无法发现这个defect,然后不得不花费几个人几个小时甚至几天的时间去定位和解决它。

再有,很多敏捷团队都会做每日构建,构建成功的前提是所有的测试都要通过,我们为了减少构建时间、测试反馈时间,花了大力气去优化和重构,使用了mock技术等等,但对测试时间的影响依然是杯水车薪。

上述问题仅仅是我们平时工作里遇见的一小部分,对于这几个问题,我们归结了两点:

  1. 测试环境不够干净
  2. 测试执行效率需要大幅提升

我们带着这两个问题,来看近年来火爆的轻量级虚拟化——容器技术,它提供了能够独立运行的轻量级虚拟化解决方案,并且也提供了一种在安全、可重复的环境中自动部署软件的方式。

传统的硬件化虚拟占用的资源比一个容器要多不止10倍。我们不敢想象在一个物理机上开上百个虚拟机是什么效果,但是要实现同样数量的容器是很正常的。容器为我们提供了隔离的运行空间,每个容器又包含了完整的用户环境。不但如此,我们还可以通过诸如ansiblepuppet、chef这样的自动化运维工具对不同的容器空间进行批量化操作等等。

从一个测试人员的角度来讲,这恰恰为我们运行测试脚本提供了丰富的土壤,我们不必担心一些依赖包悄悄地破坏我们的环境,也不再担心多人在相同的虚拟机或者硬件环境中的操作污染了环境,使defect无法重现,同时,多操作系统版本、多尺寸的移动端自动化测试也将从容器化技术中受益更多。

那么另一个问题解决起来也不算难,主流的开源自动化测试工具Selenium多年前就提供了Selenium Grid,hub/remote的机制可以很好地帮助我们设计分布式测试环境:

grid

我们可以把这样分布式的环境与自定义的容器化空间结合在一起,利用提供各种语言支持的并发工具包,让我们在安全、可重复、可移植的环境基础下,指数级提升测试运行效率,减少反馈时间:

grid2

 

大部分测试人员对日新月异的技术并不是很敏感,很多时候,我们可能会认为,这些技术的发展,并不会也并不想知道这些技术能对日常的测试工作带来多少影响,但其实很多时候看似孤立的领域,碰撞在一起会有意想不到的火花。

乔布斯曾经说,创新就是把各种事物整合在一起。当你问有创意的人是如何创新的,他们可能会感到些许愧疚,因为他们根本没有创造什么。他们只是看到了一些东西。我们对于日常工作了解得更深更广,我们就会做得越出色。

Share