如今软件开发依赖于集体的开发和测试。对于部署和测试人员来说,如何从集中的代码管理工具来获取源代码或者代码的编译包并且自动部署和测试变得非常重要。本文借助于 STAF(STAX) 和 FTP 以及 CVS 工具介绍如何自动从 FTP 或者 CVS 下载程序的更新包,并且部署到测试环境中。本文首先对自动化测试框架Software Test Automation Framework (STAF)和Software Test Automation eXecution Engine (STAX)进行简要的介绍,然后简单介绍如何安装和配置STAF(STAX)。其次本文将结合一个场景重点介绍STAF(STAX)如何利用CVS和 FTP工具进行源代码的下载、编译、分发、部署和测试。最后本文列出了使用STAF(STAX)的经验和教训。
读者可以从本文了解到 STAF(STAX) 的基本概念和用法。本文适合 STAF 的初学者。
1.STAF(STAX)
Software Test Automation Framework (STAF) 是开源、跨平台、支持多语言并且基于可重用的组件来构建的自动化测试框架。它为自动化测试建立了基础,并且提供了一种可插拨的机制支持不同的平台和语言。 STAF 采用点对点的实现机制,被用来减轻自动化测试的工作负担,加快自动化测试的进程。在 STAF 的环境中,所有的机器都是对等的,没有客户端和服务器的区分。
Software Test Automation eXecution Engine (STAX)是基于 STAF 的执行引擎。它在 STAF 的基础上,帮助用户实现测试用例的分发、部署、执行以及结果分析。STAX 使用了三种技术:STAF, XML 和 Python。简单来说,STAX 在 STAF之 上提供了一些接口,方便用户来操纵STAF进行自动化测试的实现。
我们将简要介绍一下 STAF 和 STAX 中所用到的概念和机制。
1.1 Services (服务)
STAF 基于可重用的组件来构建自动化测试框架,这些可重用的组件就是 Services(服务)。STAF 中所有的组件都是服务。服务是一系列功能的集合。STAF 本身是一个后台程序 (STAFProc),提供一种轻量级的分发机制,负责把请求转发给这些服务。
STAF 中的服务分为两种:internal (内部服务)和 external(外部服务)。内部服务被集成进 STAFProc 中,提供一些关键性的功能,比如数据管理和同步。外部服务由 STAFProc 动态装入,通过共享库(shared libraries)来访问。
STAF 提供了如下几种常用服务:
程序调用服务(Process Service):内部服务,利用此服务,STAF 可以调用外部程序。
文件系统服务(FileSystem Service):内部服务,利用此服务,STAF 可以对文件系统进行操作,比如复制,删除,查看等操作。
日志服务(Log Service):外部服务,帮助用户进行日志的记录和查看。
资源池服务(ResPool Service):外部服务,提供了对于资源池的管理和操作,如查看,创建和删除操作。
监控服务(Monitor Service):外部服务,提供对于 STAF 运行时的监控功能。
信号量服务(Sem Service):内部服务,提供了两种信号量的操作,mutex 和 event。
压缩服务(Zip Service):外部服务,提供了压缩和解压的功能。
Ping服务(Ping Service):内部服务,类似于操作系统的 ping 功能,用于检测远程的 STAF 是否运行。
变量服务(Var Service):内部服务,提供对于系统或者用户级别的环境变量的操作。
STAF 还提供了延迟(Delay Service), 帮助(Help Service), 跟踪(Trace Service)等服务,这里不一一列举。
1.2 请求-响应格式
每个服务都定义了它能接受的请求格式。STAF 通过请求来调用服务的功能,每个请求都以字符串的形式发送,这样可以保证 STAF 能够跨平台的运行。 每个请求都有三个参数,以系统-服务-参数的形式出现。第一个参数表示此请求需要被发送到的 STAF 系统,这个参数被 STAFProc 解析以便确定请求应该被本地处理还是发送到其他的 STAF 系统。 当这个请求被发送到需要处理的 STAF 系统后,STAFProc 解析第二个参数来判断哪个服务会被调用。最后,STAFProc 会把第三个参数转发给需要调用的服务,服务处理这个请求。
当处理完请求后,服务会返回两种数据:返回码和特定于请求的信息。返回码表示服务处理的结果。特定于请求的信息表示服务返回的具体数据,如果请求成功返回,这些信息将包括这次请求所请求的数据,如果请求出现错误,这些信息将包含额外的诊断信息。
完全使用字符串作为请求响应格式可以简化 STAF 的很多方面,包括与其他语言的接口,服务之间的通信,跨平台的操作等。 其他语言只需要通过一个接口 STAFSubmit() 来请求 STAF 的服务,并且只需传递三个字符串参数。服务之间也只需要通过字符串发送接收请求。
1.3 STAX
STAX 是基于 STAF 的执行引擎,它提供了一种 XML 格式的工作流语言。用户可以编写 XML 的脚本文件来通过 STAX 调用 STAF 的服务已完成自动化测试。用户可以不需要和编程语言打交道就可以开发出自己的自动化测试环境。STAX 提供如下的功能:支持并行运行,用户自定义的运行控制粒度,嵌套测试用例,控制运行时间,支持现有的 Java 和 Python 模块等。STAX 还提供了一个图形化的监控工具,通过这个工具,用户可以清晰的看出测试运行的位置,状态和出错信息等。 下面我们将通过与 FTP 和 CVS 的协作完成自动化部署来展示 STAF 和 STAX 的功能。
2.STAF(STAX) 安装配置
STAF 的安装文件可以从STAF 的网站 下载。对于不同的平台和 JVM 环境有不同的安装文件,请选择合适的文件下载。如果下载的是 jar 文件,要确保需要安装 STAF 的机器上已经安装有相应的 JRE,然后运行如下命令安装 STAF:java -jar STAF安装文件.jar 。 如果下载的是可执行文件,则直接运行即可。
STAF 的安装比较简单,只需要按照向导提示进行操作即可。安装完毕后,可以通过 STAFProc 命令启动 STAF。关闭 STAF 可以用如下的命令: staf local shutdown shutdown 。从这条命令我们可以看出上面提到的 STAF 的命令格式。local 表示 STAF 的本地系统,shutdown 表示服务, 此服务提供了 STAF 的关闭操作。第二个 shutdown 表示传递给服务的参数,指示 STAF 把本地的 STAF 服务关闭。
STAX 的安装文件也可以从STAF 的网站 下载。STAX 本身不需要安装,只需要更改 STAF 的配置文件以便 STAF 在启动的时候能够加载 STAX 服务。 从这个角度来说,STAX 是 STAF 的一种外部服务,可以根据需要来决定是否加载它。
下载完 STAX 后,将其解压到 $STAF_Install_Directory\services\stax 目录中,然后更改 STAF 的配置文件 STAF.cfg。此文件在 $STAF_Install_Directory\bin 目录下。 在 STAF.cfg 文件末尾加上如下的代码,然后重启 STAF。
代码1:STAX配置
SERVICE STAX LIBRARY JSTAF EXECUTE \
{STAF/Config/STAFRoot}/services/stax/STAX.jar OPTION J2=-Xmx384m
SERVICE EVENT LIBRARY JSTAF EXECUTE \
{STAF/Config/STAFRoot}/services/stax/STAFEvent.jar
SET MAXQUEUESIZE 10000
STAF重启之后,运行命令staf local service list ,查看输出结果,如果显示有STAX和EVENT,如图1所示,则说明STAX已经成功加载。
图 1. STAF 服务列表
SERVICE STAX LIBRARY JSTAF EXECUTE {STAF/Config/STAFRoot}/services/stax/STAX.jar 通知STAF在启动时以名字STAX(这样在STAF服务列表中,我们看到的STAX的服务名字就叫做STAX)来加载STAX.jar,也就是STAX服务。 传递的参数J2=-Xmx384m 表示更改JVM的堆栈大小。如果STAX会出现OutOfMemory错误,则需要调整这个参数,增加JVM的堆栈大小。 建议在加载STAX时总是指定这个参数,并且根据系统环境来调整参数大小。
SERVICE EVENT LIBRARY JSTAF EXECUTE {STAF/Config/STAFRoot}/services/stax/STAFEvent.jar 通知STAF在启动时以名字EVENT来加载STAFEvent.jar。
如果需要在运行STAX的机器上运行STAX Monitor (STAX任务的监控工具),则需要设置MAXQUEUESIZE,以保证STAXMonitor能够正确运行。
2.1 STAF Java 代码示例
代码2所示的是STAF Java代码示例。
代码2:STAF Java代码示例
STAFHandle handle = null;
try {
handle = new STAFHandle("Java_Sample_Test");
} catch (STAFException e) {
System.exit(1);
}
STAFResult result = handle.submit2("Linux1", "process",
"start command ls parms -l wait stdout /root/lsjava.log");
if (result.Ok != result.rc) {
System.out.println("Error starting the process ls, RC: " + result.rc);
}
result = handle.submit2("Linux1", "fs", "copy FILE /root/lsjava.log
TODIRECTORY C:/STAF TOMACHINE windows' % machineName");
if (result.Ok != result.rc) {
System.out.println("Error coping file, RC: " + result.rc);
}
在调用STAF服务之前,首先需要注册STAFHandle,所有的STAF服务调用都要通过这个句柄来进行,因此一般把这个句柄设置成静态的。通过handle.submit2()函数可以向STAF服务发送请求并且接收处理结果。
2.2 STAX脚本示例
STAX为我们简化了调用STAF服务的过程,因此我们通过STAX脚本来调用STAF服务。本节将根据一个简单的示例来简要介绍STAX脚本的语法。
代码3:STAX脚本SampleScript.xml示例
1 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2 <!DOCTYPE stax SYSTEM "stax.dtd">
3 <!-- sample1.xml - Sample of a job definition file for STAX
4 Job Description:
5 This job executes some STAF commands and sends messages to the STAX Job Monitor.
6 -->
7 <stax>
8 <script> LinuxMachine = ['Linux1', 'Linux2'] </script>
9 <defaultcall function="ListDirectory">
10 </defaultcall>
11 <function name="ListDirectory">
12 <paralleliterate var = "machineName" in="LinuxMachine">
13 <testcase name = "'listDirectory'">
14 <sequence>
15 <stafcmd>
16 <location>'%s' % machineName</location>
17 <service>'process'</service>
18 <request>'start command "ls" parms "-l" wait stdout /root/ls.log'</request>
19 </stafcmd>
20 <if expr="RC == 0">
21 <sequence>
22 <tcstatus result="'pass'"/>
23 <log message="1">'List directory suclearcase/" target="_blank" >ccessfully on %s' % machineName</log>
24 </sequence>
25 <else>
26 <sequence>
27 <tcstatus result="'fail'"/>
28 <log message="1">'Error in listing directory on %s' % machineName</log>
29 </sequence>
30 </else>
31 </if>
32 <stafcmd>
33 <location>'%s' % machineName</location>
34 <service>'fs'</service>
35 <request>'copy FILE /root/ls.log TOFILE ls%s.log TODIRECTORY C:/STAF
TOMACHINE windows' % machineName</request>
36 </stafcmd>
37 </sequence>
38 </testcase>
39 </paralleliterate>
40 </function>
41 </stax>
这个示例调用两台Linux机器上的ls命令,将结果输出到文件,根据命令返回的结果判断调用是否成功,然后复制文件到另外的STAF机器中。为了方便描述,为脚本加上行号。
STAX采用现在流行的XML语言作为其脚本语言。第一行是XML语言的标准格式,第二行表示此XML文件使用stax.dtd样式表进行验证。所有的STAX脚本文件都应该保留这两行。
3-6行是XML的注释,用来描述这个脚本的功能。
第7行是STAX脚本命令的开始符,所有STAX脚本内容都要用它起始。第8行中script 类似于编程语言中的定义变量的语句,在这里定义一个长度为2的数组LinuxMachine,其值为Linux1和Linux2。
第9-10行指定STAX脚本运行时调用的函数。第11-40行是函数的定义体。11行指定函数名为ListDirectory。
第12-39行定义一个循环,类似于Java中的for,但是这个循环是并行的。var="machineName" in="LinuxMachine" 表示此循环从LinuxMachine数组中获得输入,并且赋给machineName变量。
13行定义测试用例,在STAX脚本的运行中,可以根据运行结果来决定测试用例的结果,方便用户查看。
第14-37行表示其中的STAX脚本是顺序执行的。15-19行执行具体的STAF命令,其中location指定需要运行STAF命令的机器,可以由变量来动态指定,比如'%s' % machineName。 service表示需要调用的服务,在这里为process进程服务。request为需要传递给服务的参数。进程服务的参数分为几部分,首先是需要调用的命令"ls",parms指定需要传递给"ls"的参数"-l"。 wait表示需要等待这个命令结束才能返回。stdout表示将命令运行的结果输出到文件中去。
20-31行判断上个命令的返回结果,并根据返回结果的值设定测试用例的状态,并且记录日志以及将消息发送到STAFMonitor。expr="RC==0" 判断返回结果是否为0。 RC表示上个命令的返回结果,0表示命令执行成功。<tcstatus result="'pass'"/> 设置测试用例状态为通过,fail则表示测试用例失败。<log message="1"> 表示不仅将消息记录到STAX的日志中,而且将其发送到STAFMonitor(如果STAFMonitor处于运行状态)。
32-36 行是STAF的文件拷贝命令。fs表示文件系统服务,copy FILE指定复制文件操作,TOFILE指定目标文件的名字,STAX会用命令后面的参数% machineName替换%s,因此目标文件的名字为lsLinux1.log和lsLinux2.log。 TODIRECTORY指定目标文件夹,TOMACHINE指定目标机器。
上述STAX脚本可以用staf local stax execute file SampleScript.xml wait 执行,或者通过java -jar STAXMon.jar 启动STAXMonitor来调用。
回页首
3.自动部署更新包
图2. STAF(STAX)环境拓扑
图2是本节将要介绍的简化的场景图。软件开发分为两部分,一部分是在CVS上的最新的软件源码,另外一部分是在FTP服务器上的执行脚本。在STAF(STAX)自动部署更新包的过程中,STAX需要同时从CVS和FTP上下载最新的代码和安装脚本。 测试环境中,测试机器上都装有STAF,并且在从CVS和FTP下载代码的机器上安装有STAX。
STAX下载完代码后,将代码拷贝到用于编译的服务器上。因为代码的编译需要特殊的环境,比如需要WAS (WebSphere Application Server) 的环境,因此我们把STAX服务器和编译服务器分开。 编译服务器编译好源码之后,将其分发到部署和测试服务器上。部署服务器负责向应用程序服务器部署程序,而测试服务器则用来进行自动化测试。
本节根据这个场景介绍如何通过STAF(STAX)来实现部署和测试的自动化。