柴静采访视频完整版:使用 CruiseControl 和 STAF 建立复杂环境下的编译和测试自动化

来源:百度文库 编辑:中财网 时间:2024/04/29 15:24:11
崔 俊涛 (cuijunt@cn.ibm.com), 软件工程师, IBM
费 伽 (feijia@cn.ibm.com), 软件工程师
陈 颉 (chenjieee@hotmail.com), 软件工程师
简介: 本文结合 CruiseControl 和 STAF (STAX) 实现在复杂环境下的持续集成和自动化编译测试。在我们的解决方案中,CruiseControl 充当入口来定时触发编译和测试的过程。在更新完 CVS 代码后,CruiseControl 调用 STAX 任务来对代码进行分发、编译、部署、测试以及收集日志,最后日志会被集成到 CruiseControl 的控制台,用来显示给开发和测试人员。本文提出的测试方案不仅能够减轻测试人员的工作量,而且能够把测试结果及时反馈给开发人员,增强他们在开发过程中的信心。
标记本文!
发布日期: 2008 年 2 月 14 日
级别: 初级
访问情况 779 次浏览
建议: 0 (添加评论)
 平均分 (共 1 个评分 )
持续集成能够使开发人员和测试人员在同一个最新的版本上工作。CruiseControl 是现在流行的持续集成的软件。自动化测试能够大大减轻测试人员的工作量,减少测试过程中人为出现的错误。STAF (STAX) 是一个轻量级的自动化测试框架。
本文结合 CruiseControl 和 STAF (STAX) 来介绍一个复杂环境下的自动化测试方案。我们使用 CruiseControl 作为自动化测试的入口和调度器,用它来控制 STAX 任务的执行。STAX 通过 STAX 复杂对测试代码进行分发、编译、部署和测试。在整个测试过程中,我们不仅可以使用 JUnit 测试用例来测试代码,而且可以使用其他方式的测试用例来测试,比如 Rational Functional Tester 脚本,Robot 脚本等。
回页首
本文使用一个简化了的复杂应用场景作为运行自动测试解决方案的环境。 该应用由一个提供简单 Echo Service 的 WebService 和一个 Web 界面的 WebService 客户端组成。 用户既可以使用程序来直接访问该 WebService 也以通过在浏览器中操作该客户端来访问 WebService 提供的服务。在访问 WebService 和客户端之前,用户都需要经过身份验证来声明自己的身份。
WebService 和客户端分别运行于 Windows 和 Linux 平台上的 WebSphere 应用服务器之上。在 WebSphere 应用服务器上需要配置登录认证模块来实现用户访问前的身份认证。
在这一应用场景中,测试团队经过分析,对自动化功能测试提出了以下需求:
WebService 和客户端需要分别进行功能测试。
开发团队提供了用于配置应用程序登录模块 (LoginModule) 的自动配置部署脚本,该脚本被发布到一个 FTP 服务器上。
WebService 和客户端的源代码以及测试脚本的源代码都存放在 CVS 上,需要在测试执行前进行自动更新。
自动化测试执行需要每天自动定时运行。
测试执行的结果包括执行日志需要被测试团队和开发团队及时访问到。
针对上述需求,我们可以将这一自动化测试方案分隔为如下图所示的几个逻辑组件:

部署脚本库是指发布配置登录模块的脚本的服务器。在本文中,是一个 FTP 服务器。
源代码库是指发布被测试应用程序源代码以及测试相关源代码的服务器。在本文中,WebService 和客户端的源代码以及测试脚本的源代码都被发布在一个 CVS 服务器上。
定时器设置每天特定时间触发,本文中,定时器的功能是 CruiseControl 提供的。
自动编译工具将从源代码库中获取的测试代码和被测试代码进行编译。本文中,使用CruiseControl 结合 Ant 作为自动编译工具。
测试自动化框架负责将编译完成的被测试代码和测试代码部署到测试环境中,并调用测试自动化执行工具来执行测试。在测试执行介绍后,框架还需要收集相应的执行日志,并将执行结果和日志交由 CruiseControl 进行发布,以供测试和开发人员参考。在本文中,测试框架采用了开源的 STAF、STAX 框架。
测试执行工具是指进行测试的各种测试工具,本文中,测试工具使用了 JUnit,RFT 等。
测试环境是指运行被测试代码和测试脚本的环境。在实际应用中测试环境既可能是一个简单的Windows 服务器,也可能是由许多不同平台,不同类型的服务器组成的复杂环境。本文中,测试环境包括了不同版本不同平台的 WebSphere Application Server,以及运行测试脚本的一台服务器。
测试报表工具是将测试执行结果和日志进行呈现的工具。由于测试过程完全自动进行,只有将测试结果和日志尽可能清晰的展示在测试和开发人员面前,才能充分发挥自动测试的作用。
从上面对各个逻辑组件的描述中可以看出,测试框架在整个自动化测试方案中位于核心位置。它像控制器一样管控着其他各个组件,同时又像胶水一样把各个组件连结起来协同工作。
在分析了测试自动化需求和逻辑组件之后,我们可以给出具体的测试方案设计。

在上图中,
控制机上安装了 CruiseControl 和 STAF、STAX 框架两套工具。
编译机上安装了编译工具 Ant 以及测试执行工具 Junit 和 RFT。 其中 JUnit 测试脚本用来测试 WebService,而 RFT 测试脚本则用来测试和操作客户端。
测试机 1 和测试机 2 则分别用来运行 WebService 和客户端。
该测试方案的具体执行步骤如下:
CruiseControl 服务器在每日指定的时间自动从 CVS 服务器获取最新测试代码,完成后 CruiseControl 服务器执行一个批处理命令来启动一个 STAF 任务。
该 STAF 任务从 FTP 服务器下载最新配置登录模块的脚本到本地目录。
STAF 将 WebSerivce 和客户端的源代码,测试脚本源代码,以及测试代码分发到编译机上。
STAF 在编译机上调用编译工具 Ant 来编译被测试代码(编译出包含 WebService 的 war 和包含客户端的 war ),测试脚本源代码。
STAF 将编译出的运行时代码 (war) 通过 WAS 远程命令部署到测试机1,2中。
STAF 将配置登录模块的脚本发布到测试机1,2中,并分别在测试机上运行该脚本来配置登录模块。
STAF 在编译机上调用 JUnit 和 RFT 来运行测试代码。
STAF 将测试结果送回控制机并显示。
STAF/STAX
软件测试自动化框架( Software Testing Automation Framework,简称 STAF )是一个开源的测试自动化框架,它的设计核心理念是称为“服务”的可重用组件(例如,进程调用,资源管理,日志和监控等)。 STAX 是构建在 STAF,XML 和 Python 语言之上的执行引擎,它的出现大大的简化了测试人员的实现测试自动化的工作。STAX 同时还提供了一个强大的图形界面监控程序,使用该监控程序你可以监控并控制正在 STAF 框架中执行的任务。
本文STAF/STAX 脚本一章详细介绍了在如何使用 STAF/STAX。
CruiseControl
CruiseControl 是一个被广泛使用的用于软件持续集成的开源框架。 所谓软件的持续集成( Continuous Integration )是指一种软件开发团队频繁的将他们各自开发的组件进行集成的实践。通过软件的持续集成可以尽早的发现错误,并降低最终集成时所耗费的时间和精力。
本文配置 CruiseControl 一章详细介绍了如何配置和使用 CruiseControl。
JUnit/HttpUnit
JUnit 是一个被广泛使用的用于测试 Java 应用程序的开源自动化测试框架。JUnit 提供了十分简洁易用的编程接口来让测试人员编写测试脚本。同时搭配使用 xUnit 系列的工具,JUnit 可以完成对许多不同类型的应用的测试。
HttpUnit 是一个专门针对 Web 应用程序进行自动化测试的开源类库。它可以模拟浏览器的行为(包括表单提交,JavaScript,简单 http 认证,cookie,以及页面重定向等)来测试 Web 应用程序并且允许测试代码检查从服务器端返回的页面。
在本文中,我们搭配使用 JUnit 和 HTTPUnit 这两个工具来测试 WebService。
Rational Functional Tester
IBM Rational Functional Tester ( RFT ) 是一个用于进行自动化的功能和回归测试的工具。它使得测试人员可以测试应用程序的图形界面,并提供了数据驱动的测试能力。 RFT 支持不同平台上的各种类型的图形界面应用,常见的包括在浏览器中运行的 Web 应用界面,用 SWT 开发的图形界面等。不仅如此, RFT 还提供了多种语言版本的测试脚本和开发环境供测试人员选择,包括在 Eclipse 环境中开发 Java 测试脚本和在微软的 Visio Studio 环境中开发 VB.net 脚本。RFT 当前最新的版本为 7.0。
在本文中,我们使用 RFT 来测试 WebService 客户端。
回页首
本章介绍在自动测试前的准备工作,包括下列内容:
配置 WAS 环境变量,
删除 WAS 上的 JAAS 登录模块脚本
WAS 重启脚本
在部署服务器上准备部署脚本
在使用 WAS 开始工作前,首先要配置 WAS 环境变量 WAS_HOME,WAS_HOME 用于指向 WAS 的安装目录。下文中,在使用一些 WAS 自带的工具时,会引用环境变量 WAS_HOME 来表示 WAS 的安装目录。具体的设置方法如清单 1 所示。
[Windows Platform]set WAS_HOME=C:\Program Files\IBM\AppServerecho %WAS_HOME%[Linux Platform]export WAS_HOME=/opt/IBM/AppServerecho $WAS_HOME
清单1展示了如何配置 WAS_HOME。
在 Windows 平台中使用 set 命令进行设置,以后可以通过 %WAS_HOME% 进行访问。
在 Linux 平台中使用 export 命令进行设置,以后可以通过 $WAS_HOME 进行访问。如果要使环境变量 WAS_HOME 在系统启动时自动设置,可以将 export 语句添加到 boot.local 文件中。
在正式的测试之前,WAS 上的 JAAS 录模块需要更新到最新的版本。为了保证最新版本的成功更新,我们首先要将旧版本的 JAAS 登录模块删除(如果存在的话),如清单 2 所示。
01 loginModuleAlias = "wssecurity.KerberosToken"02 lineSeparator = java.lang.System.getProperty('line.separator')03 cells = AdminConfig.list("Cell").split(lineSeparator)04 for cell in cells :05 security = AdminConfig.list("Security", cell)06 appLoginConfig = AdminConfig.showAttribute(security, "applicationLoginConfig")07 jaasConfigEntryString = AdminConfig.list("JAASConfigurationEntry", appLoginConfig)08 jaasConfigEntry = jaasConfigEntryString.split(lineSeparator)09 entry = None10 for eachEntry in jaasConfigurationEntrys :11 jlmAlias = AdminConfig.showAttribute(eachEntry, "alias")12 if jlmAlias == loginModuleAlias :13 entry = eachEntry14 print "\nEntry found: " + entry15 break16 if entry != None :17 AdminConfig.remove(entry)18 print "\nEntry deleted: " + entry19 AdminConfig.save()
清单 2 展示了如何使用 wsadmin 脚本来删除 WAS 上的 JAAS 登录模块。WAS 的 wsadmin脚本支持 Jacl 和 Jython 两种类型的脚本语言,这个示例采用了 Jython 语言。
其中,第 1 行设置了 loginModuleAlias 变量,用于保存待删除的 JAAS 登录模块的别名。第 2 行定义了 lineSeparator 常量,用于表示换行符。第 3-4 行获取了 WAS 中的 Cell 列表,并遍历整个 Cell 列表,对每个 Cell 进行处理。第 5-6 行获取了 Cell 中的安全配置,得到 Application Login Configuration。第 7-8 行进一步获取 Cell 中的 JAAS 登录模块的列表。
第 9 行设置了 entry 变量,用于保存查找到的待删除的 JAAS 登录模块,初始值设为 None,表示未找到。
第 10-15 行是一个循环,遍历 Cell 中的 JAAS 登录模块的列表。对每个 JAAS 登录模块,第 11 行首先获取它的别名,第 12 行将别名与 loginModuleAlias 变量中保存的待删除的 JAAS 登录模块的别名进行比较,如果相同则说明这个 JAAS 登录模块就是待删除的登录模块。第 13 行将该 JAAS 登录模块保存在 entry 变量中,第 14 行打印出找到待删除登录模块的日志信息,第 15 行则退出循环。如果在循环没有找到和待删除登录模块相匹配的,则 entry 变量保持为 None。
第 16-19 行是删除登录模块的代码,第 16 行判断一下是否找到待删除登录模块,如果 entry 变量为 None,则说明没有找到,直接退出。反之,第 17 行执行删除,第 18 行打印出删除日志信息,第 19 行保存更改。
在我们的示例中,删除 JAAS 登录模块脚本是存放在一台 Linux 系统中,我们要通过这个Linux 系统上的 WAS 来删除环境中的其它系统上的 WAS 中的 JAAS 登录模块,这个操作需要通过 wsadmin 工具来远程访问其它 WAS。调用过程如清单 3 所示。
01 $WAS_HOME/bin/wsadmin.sh02 -conntype SOAP03 -host 172.16.0.12404 -username wasadmin -password passw0rd05 -lang jython06 -f DeleteLoginModule.py
清单 3 展示了如何通过 wsadmin 工具调用删除 JAAS 登录模块的方法。
第 1 行 $WAS_HOME/bin/wsadmin.sh 为 wsadmin 工具,用于管理 WAS 以及配置、应用程序部署和服务器运行时操作。
第 2 行指定使用的连接方式为 SOAP,连接方式可能的类型包含:SOAP、RMI 和 NONE。第3行指定目标 WAS 的主机名。第4行指定用来连接到远程 WAS 的用户名和密码。第5行指定脚本文件的语言采用 Jython 语言,可能的语言包括: Jacl 和 Jython 。第6行指定在目标 WAS 上要运行的脚本。
(注:第 1 行到第 6 行为一条完整的命令,此处为讲解方便分解成 6 行)
在更新(安装或删除) JAAS 登录模块之后,必须重新启动 WAS,以使更新生效。每个WAS 机器上都需要准备重启的脚本,该脚本在本地运行,控制指令通过 STAF/STAX 远程发起。 WAS重启脚本,如清单 4 所示。
[Windows Platform]%WAS_HOME%\bin\stopServer.bat server1 -user wasadmin -password passw0rd%WAS_HOME%\bin\startServer.bat server1[Linux Platform]$WAS_HOME/bin/stopServer.sh server1 -user wasadmin -password passw0rd$WAS_HOME/bin/startServer.sh server1
清单4展示了如何重启 WAS。其中,stopServer.sh 用于停止 WAS。如果启用了全局安全,则需要设定连接 WAS 的用户名和密码。startServer.sh 用于启动 WAS。
在每次测试之前,需要将 WAS 上部署的应用程序更新到最新的版本。为了保证最新版本的成功更新,我们首先要将旧版本的应用程序删除(如果存在的话),然后按照新版本的应用程序,最后启动新安装的应用程序。完整的过程如清单 5 所示。
01 import sys02 # define uninstall application03 def uninstallApp(appName):04 try:05 print '\nUninstall ' + appName + '...'06 AdminApp.uninstall(appName)07 AdminConfig.save()08 except:09 print sys.exc_type, sys.exc_value10 print '[FAIL]'11 else:12 print '[OK]'13 # define install application14 def installApp(appName, earFileName):15 try:16 print '\nInstall ' + appName + ' (' + earFileName + ')...'17 AdminApp.install(earFileName, ['-appname', appName])18 AdminConfig.save()19 except:20 print sys.exc_type, sys.exc_value21 print '[FAIL]'22 else:23 print '[OK]'24 # define start application25 def startApp(appName):26 try:27 print '\nStart ' + appName + '...'28 appMgr = AdminControl.queryNames('type=ApplicationManager,process=server1,*')29 AdminControl.invoke(appMgr, 'startApplication', appName)30 AdminConfig.save()31 except:32 print sys.exc_type, sys.exc_value33 print '[FAIL]'34 else:35 print '[OK]'36 # parse command line arguments37 argLen = len(sys.argv)38 appName = ''39 if argLen > 0:40 appName = sys.argv[0]41 earFileName = appName + '.ear'42 if argLen > 1:43 earFileName = sys.argv[1]44 # update application45 uninstallApp(appName)46 installApp(appName, earFileName)47 startApp(appName)
清单 5 展示了如何在 WAS 上重新部署应用程序。
其中,第 1 行导入了系统函数库 sys。
第 2-12 行定义了函数 uninstallApp,用于卸载已安装的应用程序。第 3 行是函数的声明,该函数包含一个参数 appName,即待卸载的应用程序名称。第 4、8、11 行是一个 try…except…else… 的异常处理模块,用于对卸载过程中发生的任何异常进行处理,并将异常信息返回给用户。第 6 行执行卸载操作,第 7 行保存卸载操作的更改。如果在卸载过程中发生异常,第 9 行将异常的类型和异常的信息显示给用户,第 10 行告知用户操作失败。反之,第 12 行告知用户操作成功。
第 13-23 行定义了函数 installApp,用于安装新的应用程序。第 14 行是函数的声明,该函数包含两个参数: appName 为待安装的应用程序名称, earFileName 为待安装的EAR包的文件名。第 17 行执行安装操作。其它代码与函数 uninstallApp 中的相应代码类似。
第 24-35 行定义了函数 startApp,用于启动应用程序。第 25 行是函数的声明,该函数包含一个参数 appName ,即待启动的应用程序名称。第 28 行获取 Application Manager 对象,第 29 行执行启动操作。其它代码与函数 uninstallApp 中的相应代码类似。
第 36-43 行解析命令行参数,第一个参数为应用程序名称,是必须的;第二个参数为应用程序EAR 包的名称,是可选的,如果省略,则在应用程序名称后加上 ’.ear’ 来代替。
第 44-47 行更新应用程序,首先删除现有的应用程序,然后按照新的应用程序,最后启动新安装的应用程序。
在我们的示例中,部署应用程序脚本是存放在一台 Linux 系统中,这台 Linux 系统称为部署服务器。我们要通过部署服务器上的 WAS 来更新环境中的其它系统上的 WAS 中的应用程序。这个调用过程是通过 wsadmin 工具来完成的,脚本和“调用删除 JAAS 登录模块”脚本类似,请参见清单 3,此处不再赘述。
回页首
STAF/STAX 脚本包括以下部分:
环境清理
下载配置 WAS 登录模块脚本
分发和运行配置 WAS 登录脚本
重启 WAS
复制源码到编译机
控制编译机编译源码
复制 WAR 到部署机器上并部署
调用测试代码
收集日志
下面我们分别介绍每个部分的脚本。
在进行自动化编译、部署和测试之前,需要对上次测试的环境进行清理,以除去上次测试的残留,保证测试结果的正确和合理。首先我们需要调用第 4 章的 WAS clean 脚本来删除 WAS 中的登录模块。
1 4 5 =0 ”>6 7 8 ‘%s’ % machine 9 ‘process’ 10 ‘start command "/root/script/CleanupEnv.sh" username "root" password11 "password" workdir "/root/script" wait stdout /root/script/cleanupEnv%s.log' 12 % machineName13 14 15 16 17 =0 ”>18 19 20 ‘%s’ % machine 21 ‘process’ 22 ‘start command "C:/script/CleanupEnv.bat" username "Administrator" 23 password "password" workdir "C:/script" wait stdout 24 C:/script/cleanupEnv%s.log' % machineName25 26 27 28 29
在清单 6 中,我们把系统分成了两套环境,Windows 系统和 Linux 系统,针对于不同的环境,cleanupEnv 脚本有不同的路径和后缀名。首先 4-29 行使用了并行的遍历来分别在各个系统上调用 cleanupEnv 脚本。在第 5 行和第 17 行中,if 语句使用的 expr 用 python 来解析,因此可以用 python 来写一些复杂的比较和判断语句。find 函数表示在字符串中查找指定的字符串。
5-16 行针对于 Linux 的系统,使用 root 用户来调用 CleanupEnv.sh 脚本。17-28 行针对于Windows 系统,使用 Administrator 用户来调用 CleanupEnv.bat 脚本。
CleanupEnv 脚本有两种储存方法:
事先存放在各个测试机器上
存放在 CruiseControl 控制机器上,然后由 STAX 来根据环境来分发这些脚本。
一般情况下,推荐使用第二种方法。脚本分布在不同的机器上,如果发生一点小的改动,极易引起脚本的不同步。使用第二种方法,不仅会避免这个问题,而且只需改动一个脚本,将极大的节省测试人员的工作量。使用第二种方法只需在第 7 行和第 19 行前面加上 STAF 复制文件的命令即可。在 Linux 上如下所示:
‘%s’ % machine ‘fs’ ‘copy FILE "D:/sample/CleanupEnv.sh" TODIRECTORY /root/script/’
把文件复制到 Linux 上需要注意一个问题,就是文件的某些属性可能没有被复制,比如可执行属性,因此需要使用下面的命令来更改文件的属性,以便用户能够执行此文件。
‘%s’ % machine ‘process’ ‘start command "chmod +x /root/script/CleanupEnv.sh"’
在删除上次自动化测试配置的登录模块之后,我们需要从 FTP 下载最新版本的配置登录模块的脚本。本文使用 Windows 自带的 FTP 命令来完成脚本的下载。FTP 上存放了不同时期的版本,每个版本使用文件名+时间戳的方式来区分,而 FTP 命令并没有提供下载最新脚本的功能,因此我们需要自己来判断那个脚本是最新的。首先利用 FTP 的 ls 命令来列出所有的版本文件,通过 java 程序来判断哪个是最新的版本,最后再利用 FTP 命令来下载最新的版本。STAX 脚本如下所示:
'local''ftp''-s:C:/Sample/ftpconf/ftplist.conf''C:/Sample''local''java''-cp . fileParsing.ParseBuildTime temp.txt ftptemplate.conf ftpdown.conf''C:/Sample' 'local''ftp''-s:C:/Sample/ftpconf/ftpdown.conf''C:/Sample'
其中第一个 Process 命令从 FTP 服务器上获取所有的版本文件信息,保存到 temp.txt 文件中。ParseBuildTime 用来从版本文件列表 temp.txt 中找出最新的版本文件,并且根据提供的 FTP 模板文件 ftptemplate.conf 生成 FTP 脚本 ftpdown.conf,供 STAX 脚本调用下载最新的版本文件。第三个 Process 命令调用 ftpdown.conf 从 FTP 服务器下载最新的版本文件。
清单 10 显示了 FTP 模板文件,它是由一系列 FTP 命令组成。
open ftp.ibm.comuserpasswordbinarypromptcd /sampledirectorylcd C:\Sample\buildget "