基于测试需求的持续集成环境研究与实践

2017-07-12 22:14李兴凯曾东旭陈敏
软件导刊 2017年6期
关键词:自动化测试

李兴凯+曾东旭+陈敏

摘要:基于软件开发中的测试需求,分析和研究持续集成环境问题,提出最小持续集成环境概念,并给出典型最小构成。对软件开发各阶段的不同测试进行可持续集成需求分析,指出多设备环境配置是其中最不稳定、最易出错和最需要持续集成的。对4G LTE无线网络的多设备环境配置需求及对持续集成工具的Web访问局限性进行了分析,并在Jenkins平台上实现了Web访问的二次封装。

关键词:持续集成;Jenkins;自动化测试;Web访问

DOIDOI:10.11907/rjdk.171128

中图分类号:TP306

文献标识码:A 文章编号:1672-7800(2017)006-0011-04

0 引言

持续集成(Continuous Integration,CI)思想源于软件开发中的极限编程(eXtreme Programming,XP),是其12个最佳实践中的1个[1]。持续集成是为了保障产品质量,实现开发测试的快速迭代,尽早发现并解决问题。越来越多的人开始接受持续集成理念,自觉或不自觉地在项目中借鉴持续集成思想,使用持续集成工具,甚至开发自己的持续集成环境和工具。

1 最小持续集成环境

随着软件规模的不断增大,测试用例数量随之不断增长,手工配置系统应用环境,手工进行软件测试变得越来越低效。用自动化脚本维护测试用例、执行测试、返回测试结果的自动化测试成为趋势。最小持续集成环境只需要一个任务定时启动器和一个执行自动化测试的脚本,是实现持续集成的最简单方式。如图1所示,自动化测试脚本用于实现项目的具体测试需求,在Linux环境下可以用Crontab命令作为任务定时启动器,在Windows环境下可以用计划任务Bat命令作为任务定时启动器。这样,用一个自动化脚本和一个周期性配置命令就能搭建出最简单的持续集成环境,但这种最小持续集成环境所实现的功能也相对简单。 Crontab和Bat都是特定格式的命令文本,定时任务的查看和维护需要相应的背景知识,对于普通测试人员而言不够方便和直观。

2 软件开发中的测试需求和可持续集成需求

2.1 测试需求分析

版本同步——软件项目一般是多人同时开发,不同模块和功能完成的时间前后不一,在执行编译命令前需要进行代码同步。

版本构建——用于将已完成的代码进行编译,如C++和Java等编译性语言可分别使用GCC和Javac等编译命令产生可执行的二进制文件,而解释类语言一般不需要编译。对于产品版本分支较多的情况,可能有多个选项控制产生多个不同目标版本。

单元测试——主要用于函数级和类级的测试,可用Gtest和Junit等测试框架编写用例。而代码覆盖率检查和代码静态检查也可以划归为单元测试范畴,可使用Gcov和Jcoco等工具检查代码覆盖率,可使用Cpplint和Jtest等工具进行代码静态检查。

集成测试——在单元测试的基础上,对组装后的模块或子系统进行测试,一般用代码和脚本模拟外部行为,对集成模块进行测试。

系统测试——将已经确认的软件、硬件、外设、网络等元素结合在一起,对整个系统进行确认性测试,一般用真实设备对系统进行测试。

负载测试——用于测试系统在不同负载情况下的性能表现和持续正常运行能力,一般采用高性能服务器作为测试的触发源。

验收测试——用于测试产品的功能和性能是否与需求说明书一致,如α测试是公司内部人员模拟真实用户的操作行为和习惯对产品进行测试,而β测试是真实用户直接对产品进行测试。

如图2所示,版本同步、版本构建和单元测试一般可以在单机环境中完成,而集成测试和系统测试则可能涉及多个模拟或真实的外部设备,负载测试根据具体实现不同,可以只在单机完成,也可能涉及多个外部设备。

版本同步是开发人员将本地代码与远端服务器代码进行同步,更新到最新版本或某个指定版本,一般只在开发人员的工作主机中完成。版本构建和单元测试虽然可以只在单机中完成,但为了提高构建和测试效率,也可以将单机串行任务划分为多个任务,分发到多个服务器上并行执行,在多个服务器执行完毕后,将执行结果返回给主控服务器,由主控服务器判断整个任务是否成功。将单机串行任务变成多服务器的并行任务,可以大大提高构建和测试的执行效率,但也使单机测试变成了涉及多个外部设备的协同测试,增加了持续集成实现的复杂度。

不同的软件测试需求,涉及的实际网络环境也各不相同,对于可能涉及多个外部设备的集成测试、系统测试、负载测试,要想实现持续集成,还必须考虑产品的版本部署和多个外部设备的环境配置等准备工作。

2.2 可持续集成需求分析

随着开发者对持續集成思想的不断接纳,持续集成实践早已不再局限于极限编程领域。从软件开发测试流程来看,版本同步、版本构建、单元测试、集成测试、系统测试、负载测试等阶段都可以通过脚本实现自动化,都有持续集成需求。而验收测试一般是产品研发人员与用户共同参与的测试,测试过程有很多的人工操作和干预,较少对其纳入持续集成范畴。如图3所示,是从测试需求角度分析软件开发过程中的可持续集成部分。

版本同步是指用CVS、SVN、ClearCase、Git等版本控制工具将代码更新到最新版本或指定版本,这个过程可以用脚本封装起来,对于指定版本情况,可以设计脚本接受参数输入。版本构建是指对刚刚同步过的版本进行编译和链接。根据测试阶段和目的不同,构建产生的可能不是最终的产品版本,如表1所示。

单元测试时,产生的是供单元测试用的版本,版本中除了包含产品代码外,还包含对产品代码进行测试的桩函数(Stub)代码和测试用例。集成测试时,由于可能涉及辅助测试的模拟设备,构建产生的版本中可能包括与模拟设备相关的接口代码。系统测试和验收测试时,一般是将产品设备放在真实的系统应用场景中,由于不再涉及模拟设备接口代码,因此应该产生正式版本。

负载测试比较特殊,不是验证产品的功能,而是检验产品的最大用户数、最快响应时间、最高处理能力等性能指标。如果实现方式基于产品本身系统,版本中包含的内容就与单元测试类似;如果实现方式基于模拟设备,版本中包含的内容就与集成测试类似;如果实现方式是真实设备直接测试,版本中包含的内容与系统测试和验收测试一样,只需要编译正式版本即可。

当软件项目规模较大时,如果编译时间较长,可以用脚本实现多服务器并行编译,此时还需考虑编译的任务分发和结果回收等问题。

本文版本同步和版本构建划分为两部分,因为版本同步一般在开发者的单机环境中完成更新,而版本构建可交由多服务器并行实现以提高效率,是为了突出两者持续集成的环境差别,实际项目中可以一起划分到源代码的版本管理和维护范畴。

多设备环境准备——对于有多个网络设备的环境,一般是在版本构建完成后,将生成的版本部署到被测产品设备中。

由于存在多个网络设备,可能涉及多个网络设备的连接和配置问题。如果测试时使用了模拟其它网元的模拟设备,就要考虑模拟设备的连接和配置问题;如果模拟设备与被测产品有版本匹配问题,还要考虑模拟设备的版本同步、版本构建和版本部署等,相当于同时管理两套代码的部署问题。对于有多个网络设备参与的测试,设备之间的连接和配置必不可少,而且是测试环境搭建中最不稳定、最易出错和最应该实现持续集成的部分。如果每次都是人工手动配置,出错的概率会很高,一般可以用脚本实现自动化配置,避免由于人工操作失误而导致配置失败。

测试执行——是持续集成的最核心部分,用测试用例验证产品是否满足设计需求。在具体执行测试前,要考虑测试用例列表准备、执行顺序设置、失败重试次数设置、日志目录设置等自定义的选项。这种测试前的准备一般用脚本实现,用户只要输入参数即可完成设置。对于把测试用例从单机串行执行改为多服务器并行执行的情况,测试脚本还要考虑如何进行用例分发、结果回收、报告生成、日志归集等功能。

日志归集和结果报告——在测试执行完成后,要对生成的日志文件进行归集以备后用,要对执行的结果进行分析以判断成功或是失败,还可以对比历史结果生成执行成功趋势图,并用邮件的方式将测试结果、执行时间、日志路径和链接地址等信息发送给相关开发测试人员。

版本部署——在所有的测试执行完成后,如果没有出现测试用例失败,就可以将经过测试的产品版本部署到实际应用环境中。

在多设备环境配置时,也涉及版本部署问题,但其是将各网络设备的版本部署到实际测试环境中,包括单元测试的版本、集成测试的模拟工具版本、系統测试的被测产品版本。而在被测产品版本成功通过所有测试后的版本部署,是将经过验证的真实软件产品版本部署到实际的应用环境中。

3 持续集成工具选择

明确了软件的测试需求和可持续集成需求后,就要考虑采用什么样的测试工具。在项目初始阶段,为了实现快速的持续集成环境搭建,可以用本文开头所述的“最小持续集成环境”方案。但随着项目规模不断增大,项目数量不断增多,“最小持续集成环境”的任务启动和进度监控等显得不够直观。而且多个用户通过配置crontab或bat文件管理持续集成任务也容易造成配置冲突,缺少全局性的任务规划和管理。如果多个用户在同一个时间段配置了某些很耗系统资源的任务,就会造成在某段时间内系统资源占用率高、任务执行耗时长、甚至日志文件读写冲突等问题。

针对以上可能存在的问题,可以考虑选择CruiseControl[2-3]、Apache Continuum[4]、Jenkins/Hudson[5](Jenkins源于Hudson早期版本分支)等第三方持续集成工具。以近年来广泛应用的开源项目Jenkins为例,其具有可定制化的项目Web配置界面,在项目建立时可以配置源码管理、构建触发器、构建环境、构建、构建后操作和通用设置6方面内容,涵盖了项目测试时进行持续集成部署的各个方面。配置时可以直接在浏览器中输入要执行的脚本或路径;在脚本启动后,可以通过Web页面实时查看执行进度;在脚本执行完成后,图形化标记结果成功或失败,并可将执行结果发送到配置的邮件地址。

Jenkins官方网站中对其基本定位是一个可以支持多种自动化模式的自动机,支持任务串联和并联,并形象地这种串并联后任务执行模式称为管道(Pipeline)[6]。如图4所示,是将图2的软件测试需求与图3的软件开发过程中的可持续集成部分结合,将实现不同功能的众多小任务像管道一样连接起来构成一个持续集成的大任务。Jenkins管道模式支持多任务并行,在完成必要的准备任务后,完成特定功能的众多小任务可实现并行启动,合理规划和设计小任务的串并联,可以大大提高任务的执行效率。

持续集成的目标是实现软件开发的持续迭代,持续集成工具为这一目标提供了更加简单和高效的实现方式,加上针对具体项目的自动化测试脚本,就使得原本必须手动执行的构建、测试、部署等工作变得不再困难。

4 基于Jenkins的无线4G LTE网络持续集成实践

4.1 多设备环境配置

不同于单机软件,有多个网络设备时涉及多个网元,配置更复杂,更容易出错。如图5所示的无线4G LTE网络拓扑结构,包括基站(eNodeB)、用户设备(UE)和核心网(EPC)等多个网络设备。其中,深色eNodeB是真实被测设备,浅色eNodeB是辅助测试设备,可能是真实的,也可能是模拟的。多设备之间的通信接口,根据4G LTE网络标准协议规定,eNodeB和UE之间的是uu接口,eNodeB和EPC之间的是s1接口,eNodeB之间的是x2接口。对eNodeB的测试就是验证eNodeB与UE和EPC之间的信令流程是否满足协议规定,数据传输是否稳定可靠。而在测试之前,保证eNodeB与众多网络设备之间的连通性,配置设备运行参数和检查产品版本匹配等问题,都是多设备环境配置必须考虑的。

以工作中实际的4G LTE项目为例,使用上述可持续集成需求分析方法进行多设备环境配置需求分析。如表2所示,系统测试和集成测试只有多设备环境,对系统测试而言,涉及两个真实eNodeB的版本部署和参数配置、真实UE参数配置、真实EPC版本部署和参数配置;对集成测试而言,涉及一个真实eNodeB版本部署和参数配置、一个模拟eNodeB版本部署和参数配置、模拟UE参数配置、模拟EPC版本部署和參数配置。单元测试用桩函数(Stub)屏蔽底层接口消息,有单服务器环境和多服务器环境两个版本,多服务器版本除了考虑单个服务器配置外,还要考虑多服务器并行测试时的任务分发和结果回收;负载测试也有单机环境和多设备环境两个版本,负载测试的单机环境与单元测试的单机环境类似,也是由桩函数(Stub)屏蔽底层接口消息,只是测试用例更偏向大容量、高负载、多并发的应用场景;负载测试的多设备环境网络组成与集成测试类似,除了一个真实的被测eNodeB之外,其它设备都是模拟的。4.2 Web统一访问页面实践

在Jenkins服务器搭建完毕后,任务的建立、访问和配置都是通过Web页面完成,这使得任务的参数配置、脚本嵌入、进度监控、日志查看等都变得十分方便。Jenkins的任务显示由横向选项和纵向列表两部分组成,如图6所示,是无线4G LTE项目Jenkins服务器搭建完毕后的Web页面。

随着项目数量不断增多,Web访问界面的选项卡变得越来越拥挤,如果项目的名字过长,一个页面只能放置有限的几个项目。虽然可以在一个项目中建立多个子项目,并在子项目中再建立多个孙项目,建立起层级关系。但这样建立起来的Jenkins项目层级太多,划分的子孙项目太多,某些子孙项目可能只是为了实现启动、停止、用户认证或服务器连接等小任务而建立。更重要的是如果单个项目层级太多,日志文件就被分散在多个子孙项目中,当某个项目执行失败时,为了查看这个失败日志,就要一层层地进入子孙项目,访问不够方便,项目关系不够明确。

基于上述考虑,可以尝试对Jenkins的Web访问接口进行二次封装,不让用户直接访问Jenkins的默认Web页面,而是通过如图7所示的定制界面进行任务的配置和提交。在点击提交按钮后,用户会收到任务开始邮件,给出任务执行的链接地址,可以随时监控任务进度;在任务执行完成后,用户将收到结束通知邮件,给出日志文件的链接地址。如果任务失败,还会给出失败子任务或孙任务的链接地址,不必一层层地进入子孙项目查找;如果任务没有失败,用户只需查看任务开始邮件和成功结束邮件,甚至无需知道Jenkins的存在。

这种对Jenkins Web页面进行二次封装的任务提交方式,让用户只关注项目本身,不必关注具体用什么持续集成工具实现,只有在查看日志时才会访问到Jenkins的Web页面。相比于使用Jenkins本身的Web服务,二次封装方案对用户屏蔽了持续集成工具,增加了Web服务器的开发成本,但实现了让开发人员聚焦于开发和测试,而不是工具的目的。这种二次封装方案,可以用于大项目合并,比如某些项目已经搭建了基于Jenkins的持续集成环境,而另外一些项目搭建了基于CruiseControl的持续集成环境。在项目合并时,可以统一Web访问接口,屏蔽掉原来两个项目的持续集成工具,只关注任务提交和执行结果,而将持续集成工具作为任务管理和日志查询的工具。

5 结语

持续集成的目的是为了保证产品质量,在软件开发过程中更好地支持快速迭代,高质量地完成开发和测试任务。持续集成工具的选择要根据项目的实际需求和网络环境,可以用最小持续集成环境,也可以自主开发持续集成工具,还可以使用Jenkins/Hudson、Apache Continuum、CruiseControl等持续集成工具。第三方持续集成工具普遍通过Web页面进行任务访问和配置,经过二次封装的统一Web访问页面,可以让用户更加聚焦于开发和测试,而不是工具本身。在项目中选择什么样的持续集成环境和工具取决于项目的具体需要,还要考虑团队成员的知识储备和能力等问题。

参考文献:

[1] KENT BECK.Extreme programming explained:embrace change[M].Addison-Wesley Professional:US ed Edition,1999.

[2] KEVIN A LEE.IBM Rational clearcase,ant,and cruisecontrol: the java developer's guide to accelerating and automating the build process[M].1 edition.IBM Press,2006.

[3] CruiseControl初探[EB/OL].http://cruisecontrol.sourceforge.net/index.html.

[4] Continuous integration and build server[EB/OL].http://continuum.apache.org/.

[5] Register for jenkins world 2017[EB/OL].https://jenkins.io/.

[6] Jenkins (software)[EB/OL].https://en.wikipedia.org/wiki/Jenkins_(software).

(责任编辑:孙 娟)

猜你喜欢
自动化测试
浅谈空调控制器自动化测试