标题：STAF
简介
STAF (SW Test Automation Framework) 是一个自动化测试框架，用以提升测试用例和测试环境的可重用性以及自动化的程度。STAF 为测试人员提供了一个端到端的自动化测试解决方案。[1]
各个服务端点（称作STAF客户端）是对等的，从一个端点可直接调用另一端点（在另一台机器运行的程序）提供的服务。
服务
[2-3]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), 帮助请求/访问格式
每个服务都定义了它能接受的请求格式。STAF 通过请求来调用服务的功能，每个请求都以字符串的形式发送，这样可以保证 STAF 能够跨平台的运行。 每个请求都有三个参数，以系统-服务-参数的形式出现。第一个参数表示此请求需要被发送到的 STAF 系统，这个参数被 STAFProc 解析以便确定请求应该被本地处理还是发送到其他的 STAF 系统。 当这个请求被发送到需要处理的 STAF 系统后，STAFProc 解析第二个参数来判断哪个服务会被调用。最后，STAFProc 会把第三个参数转发给需要调用的服务，服务处理这个请求。 
当处理完请求后，服务会返回两种数据：返回码和特定于请求的信息。返回码表示服务处理的结果。特定于请求的信息表示服务返回的具体数据，如果请求成功返回，这些信息将包括这次请求所请求的数据，如果请求出现错误，这些信息将包含额外的诊断信息。 
完全使用字符串作为请求响应格式可以简化 STAF 的很多方面，包括与其他语言的接口，服务之间的通信，跨平台的操作等。 其他语言只需要通过一个接口 STAFSubmit() 来请求 STAF 的服务，并且只需传递三个字符串参数。服务之间也只需要通过字符串发送接收请求。
技术特点
1.将环境需求最小化（包括硬件与软件）  服务列表2.在各种语言中都很容易使用，包括Java，C/C++，Rexx，Perl，TCL，及命令行shell环境
3.易于扩展，让用户能方便的创建一个服务插入到STAF体系中
STAF比较适应需要构造复杂测试环境的场合，复杂测试环境通常是分布式的，通过STAF将测试任务分发到不同的测试环境去执行，可以方便的测试机的测试 脚本，可以方便的收集测试结果，另外，执行引擎STAX（Software Test Automation eXecution Engine）让STAF的使用变得更简单，测试人员只需要配置XML文件便实现STAF任务管理。
功能
STAX 是基于 STAF 的执行引擎，它提供了一种 XML 格式的工作流语言。用户可以编写 XML 的脚本文件来通过 STAX 调用 STAF 的服务已完成自动化测试。用户可以不需要和编程语言打交道就可以开发出自己的自动化测试环境。STAX 提供如下的功能：支持并行运行，用户自定义的运行控制粒度，嵌套测试用例，控制运行时间，支持现有的 Java 和 Python 模块等。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 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能够正确运行。
6.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服务发送请求并且接收处理结果。
6.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 successfully 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来调用。
注意
具体的项目经验中，也发现不少问题，比较需要注意的是：一、是在stax job的XML文件中，其调用WINDOWS的命令时，文件分隔符为"/"，而不是"\"。二、在编写STAX JOB的XML时，如用到Altova XMLSpy等工具，需要STAX的DTD,可以用以下命令得到
set STAF_QUIET_MODE=1 (在Unix中: export STAF_QUIET_MODE=1)
STAF local STAX GET DTD > stax.dtd
set STAF_QUIET_MODE= (在Unix中: unset STAF_QUIET_MODE)
外界评价
STAF(软件自动化程序框) 提供了一个自动化测试的平台，可与其他测试工具一起，帮助我们进行自动化测试的更新、编译、部署和测试。STAX为STAF提供了一个执行引擎，帮助加快STAF程序的开发和部署。 因此利用STAF和STAX可以减少测试的工作量和复杂度，加快软件测试的流程，缩短测试周期。