移动开发流水线建立以及自动化测试

工业时代流水线的发明将生产任务的效率大大提升。同样,在软件开发过程中流水线的建立也能帮助我们更好的产出、提升效率。

流水线的建立准则应该符合每个团队自己的需求,比如你的团队管理策略、分支管理策略,接下来以我们最近的给客户做的案例进行总结说明:

我们首先需要制定我们流水线的策略,需要哪几个任务,进行任务的拆分:

iOS:

| 主分支每次提交进行构建触发单元测试 
|   
|--功能测试构建分发
|   |
|   |--各个执行功能测试的节点并行执行功能测试
|       |
|       |--聚合各个节点的功能测试结果输入报告
|
|--adhoc分发通知测试人员
|
|--enterprise分发通知测试人员
|
|--appstore提审核      
|

Android:

| 主分支每次提交进行构建触发单元测试 
|   
|--功能测试构建分发
|   |
|   |--各个执行功能测试的节点并行执行功能测试
|       |
|       |--聚合各个节点的功能测试结果输入报告
|
|--打release包通知测试人员测试
    |
    |--打各种渠道包

其中的功能测试板块由客户的测试团队负责日常的监控以及维护,不干扰开发团队日常的开发。不是整个任务成功的必要条件,而在我之前的开发项目中,功能测试是由开发人员与测试人员一起结对书写,因此会把它作为发测试包的前置步骤,这点根据每个团队的实际情况考量。

工具集:

工欲善其事,必先利其器。要想自动化整个过程,离不开工具的支持。


通用:

Jenkins:用的最广持续集成工具,但是本身并不提供流水线功能,需要插件支持

Gem:ruby包管理工具,比如我们执行功能测试Appium、Calabash等都是通过gem来安装的。

rbenv:管理ruby,用它来统一ruby环境。

bundle:用来管理gem包,比如gem包的版本等。

rake:用ruby时间的类似于make的构建工具,我们的任务脚本使用rake来写的,选自己顺手的就好了。

cucumber:基于BDD的自动化测试框架

iOS:

shenzhen:对,深圳,作者写了一堆用城市命名的工具。这个是用来构建ipa以及分发的,不过我只用了它的分发功能,还是直接用的xcodebuild构建。

calabash:iOS端用来进行自动化功能测试的工具,基于cucumber。

Android:

Appium:类似于calabash的自动化测试框架。之所以没有在安卓上用calabash,是因为项目中用了蚂蚁金融的一个SDK,其对测试不太友好,不支持像calabash这样使用Instrumentation的框架。


关键设计:

持续对主分支进行构建:

我们需要保证开发团队的每一次代码提交都是能工作,能通过测试的,相比传统开发过程中在最后关头进行测试,大大降低了风险。

如下图,需要在任务配置中写上执行策略,比如你想每两分钟去检测一次你的代码库有没有代码变化,如果有变化,Jenkins会立刻开始执行构建。

每两分钟检测一次代码库

拉取下了代码之后之后需要构建并执行单元测试,iOS使用xcodebuild,安卓使用gradle

如何串连流水线:

当构建没问题之后,我们需要在构建后步骤中将下游的任务串连起来,这里有两种方式,一种是自动触发下游任务,一种是手动触发。比如我们的发包步骤就是运营人员手工操作,执行功能测试到合并报告就是自动进行的。

自动触发: 这里需要选择Trigger parameterized build on other projects,指明下游任务的名字。根据需要制定触发条件,以及传递的参数等。

自动触发截图

手动触发:

这里需要选择Build other projects(manual steps),我们需要指定下游任务的名称。传递git commit过去是为了保证下游任务产品代码与当前保值一致,除此之外还会传递一些预定义的参数到下游。

手工触发截图

并行执行功能测试

需求是需要在多台节点上并行地执行功能测试,比如我要在天津的一台机器用三星 note跑测试,我要在成都的一台机器用 另外一台手机跑。

为了解决这个需求,我需要加入一个多配置的任务,然后在Configuration Matrix中进行配置,如图,把能够执行这个任务的多个节点给选上。

Configuration Matrix

如何合并多个cucumber报告

这里分两步,首先需要把每个节点的测试结果收集起来,然后传递到下游去,通过传递归档文件就可以完成这一步。比如我任务完成了之后会生成一个build目录,我需要把多台节点的这个目录传递过去。这里需要注意的点在于,每个节点生成的结果会加上自己的机器前缀。比如会像这样mac_chengdu/build,我们需要使用通配符 ****/build/**表示。

接下来是合并,因为cucumber生成的报告结果可以是json的,这一步就是在解析json的结果,我fork了cucumber-html-reporter对进行修改,做成了一个node的命令行工具,可以参考这里

关于自动化测试

iOS和安卓的开发中本身就提供单元测试的支持,比如iOS提供XCTest,安卓有JUnit,根据需要进行调整,比如iOS上我使用的Kiwi

单元测试比较简单,主要看团队对这东西的认识。主要聊一下功能测试这块遇到的坑。

先说iOS,iOS上采用的calabash,一个是项目组之前也在用,二个是我在调研了appium之后,发现appium最新版本才开始支持XCUITest做功能测试,存在一些bug且功能不够完善,因此果断上calabash。

在安卓遇到的坑相对来说多一点,首先calabash在安卓上底层是用的Instrumentation,调研过calabash的源码发现如果要让它支持UIAutomator的话,基本上等于重新造一个轮子了,因此如果你的产品不支持Instrumentation的话需要注意了。

那么appium呢,appium 配合cucumber在安卓上看起来不错的。我开开心心地用了起来,结果看报告发现这家伙在失败的时候不会主动截图,看样子得自己去实现了,好在cucumber提供了一些hook的方法,比如可以在每个执行步骤之后做点什么。 我一开始是在cucumber的AfterStep中加入了截图的方法,可是发现并没有什么用,后来查了一会儿发现已经有人给cucumber提过这个[issue](bundle exec cucumber #{feature}--tags ~@pending --format json --out #{BUILD_DIR}/functionals.json --format NewHtml --out #{BUILD_DIR}/functionals.html),原来cucumber设计上就是这样考虑的,失败了的步骤不允许hook。 既然cucumber这一层做不了,那只能在appium这一层做手脚了。经过观察,失败场景大多是找不到元素,因此我需要解决的主要问题是在找不到元素的时候进行截图。我在appium-lib中找到了driver.rb,看了下它提供了几个查找元素的方法,底层是用的selenium-webdriver进行操作,那么我的需求应该在driver这层就能够解决,我只需要在这几个方法执行失败后加上截图保存的方法就好了。Ruby我不熟悉,我查了下有几种方式可以解决,你可以新建一个子类重写这几个方法,你可以利用ruby的动态性把这几个方法给动态的替换了。我这里采用的是第二种方式,代码如下:

module DriverExtension
    def store_callback_after_fail(&block)
        @execute = block
    end

    def take_screenshot_when_fail
        @@screenshot_count ||= 0
        $filename = "./build/" + "Screenshot-" + "#{@@screenshot_count}" + ".png" 
        File.delete($filename) if File.exist?($filename)
        screenshot($filename)
        @execute.call($filename)
    end

    def find_element(*args)
        begin
            result = super 
            result
        rescue Exception => e
            take_screenshot_when_fail
            raise 
        end
    end

    ...
    ...
end

module Appium
    class Driver
        prepend DriverExtension
    end
end

采用流水线之后可以大幅度的减少人力成本,比如我们的客户之前还有安排同事专门负责构建打包上传等任务,代码出了问题也很难追溯到底在哪一步出了错。现在整个流程自动化了后,开发人员只需要更加专注于手中的开发任务,测试人员想什么时候测就什么时候测,要做的只需要点个按钮就好,是不是很赞!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏点滴积累

geotrellis使用(三十七)COG 基础介绍

前言 Geotrellis 已经迭代到了 2.0 版本(截止写作此文时为 2.0.0-SNAPSHOT 版),2.0 版多了很多新的特性,其中最重要的应该就是 ...

43014
来自专栏cloudskyme

15个nosql数据库

1、MongoDB 介绍 MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。主要解决的是海量数据的访问效率问题,为WEB应用提供可扩展的高性能数...

3636
来自专栏Golang语言社区

前后端分离开发模式下后端质量的保证 —— 单元测试

概述   在今天, 前后端分离已经是首选的一个开发模式。这对于后端团队来说其实是一个好消息,减轻任务并且更专注。在测试方面,就更加依赖于单元测试对于API以及后...

4579
来自专栏京东技术

单元测试高效之路——持续集成

互联网软件的开发和发布,已经形成了一套标准流程,最重要的组成部分就是持续集成(Continuous integration,简称CI)。

1800
来自专栏互联网高可用架构

如何设计一款多场景分布式发号器(Vesta)

3763
来自专栏程序员宝库

后端好书阅读与推荐(续四)

这里依然记录一下每本书的亮点与自己读书心得和体会,分享并求拍砖。 Docker生产环境实践指南 Docker生产环境实践指南 (豆瓣:https://book....

4936
来自专栏刘君君

Rest Notes-架构上的教训(论文部分完结)

1716
来自专栏ThoughtWorks

2015.5 技术雷达 | 工具篇

(点击图片可以查看大图) 尽管依赖管理的概念并不新奇,在很多技术栈下它甚至已经被作为一种基础开发实践,但在PHP 社区却并非如此。Composer(getcom...

3735
来自专栏weixuqin 的专栏

django 实现电子支付功能

  思路:调用第三方支付 API 接口实现支付功能。本来想用支付宝来实现第三方网站的支付功能的,但是在实际操作中发现支付宝没有 Python 接口,网上虽然有他...

1662
来自专栏北京马哥教育

15个NoSql数据库

随着互联网web2.0网站的兴起,非关系型的数据库现在成了一个极其热门的新领域,非关系数据库产品的发展非常迅速。而传统的关系数据库在应付web2.0网站,特别是...

4028

扫码关注云+社区

领取腾讯云代金券