STAF/STAX 基于 IBM i 的简介
Software Test Automation Framework (STAF) 是开源、跨平台、支持多语言、基于可重用组件的自动化测试框架,它为自动化测试建立了基础,并且提供了一种可插拨的机制支持不同的平台和语言。在 STAF 中,可重用的组件被称为服务,STAF 有内部、外部两种类型的服务。在 STAF 的环境中,所有的机器都是对等的,没有客户端和服务器的区分。它通过运用点对点的实现机制,减轻了自动化测试的工作负担,加快了自动化测试的进程。
Software Test Automation eXecution Engine (STAX) 是基于 XML 的执行引擎。它作为 STAF 的一个外部服务,在 STAF 的基础上,帮助用户实现测试用例的分发、部署、执行以及结果分析。STAX 使用了三种技术:STAF, XML 和 Python。简单来说,STAX 在 STAF 之 上提供了一些接口,方便用户来操纵 STAF 进行自动化测试的实现。
STAF 的安装 / 配置
按照以下的步骤,完成 STAF 的安装。
- 登录 IBM i,创建一个临时文件夹 /QIBM/stafinst,用来存储 STAF 的安装包。
- 到 STAF 官方网站上(http://staf.sourceforge.net/getcurrent.php)下载 IBM i 平台的 STAF 安装包(例如:STAF342-aix.tar.gz,STAF 在 i 平台上是运行在 PASE 环境下)到 /QIBM/stafinst 下面。
- 在绿屏上输入 CALL QP2TERM,切换到 PASE 下。
- 通过如下命令,如代码 1 所示。在 /QIBM/stafinst 下,解压 STAF342-aix.tar.gz,运行 STAFInst 完成 STAF 的安装。
代码 1. 安装 STAF 示例代码
cd /QIBM/stafinst gunzip STAF323-as400.tar.gz tar xf STAF323-as400.tar cd staf . ./STAFInst -target /QIBM/staf – acceptlicense
安装 STAF 后的目录结构,如图 1 所示。
图 1. STAF 安装目录结构
- 删除临时文件夹 /QIBM/stafinst。
完成安装后,在绿屏上输入 CALL QP2TERM,切换到 PASE 下。然后,切换到 STAF 的安装目录 /QIBM/STAF,运行 STAFEnv.sh,来设置必要的环境变量。如代码 2 所示。
代码 2. 执行脚本示例代码
cd /QIBM/STAF . ./STATEnv.sh
STAFEnv.sh 里必须包含以下环境变量的设置信息。如代码 3 所示。
代码 3. 环境变量信息
export PATH=/QIBM/staf/bin:$PATH export LIBPATH=/QIBM/staf/lib:$LIBPATH export CLASSPATH=/QIBM/staf/lib/JSTAF.jar:$CLASSPATH export STAFCONVDIR=/QIBM/staf/codepage export QIBM_MULTI_THREADED=Y export QIBM_JAVA_PASE_STARTUP=/usr/lib/start32
运行 STAFProc & 在后台启动 STAF。如图 2 所示,说明 STAF 已成功启动。
图 2. STAF 启动信息
最后,退出 PASE,在绿屏上执行 WRKACTJOB 命令查看 STAFProc 是否运行,如图 3 所示结果。
图 3. STAF 的后台进程
默认情况下,STAF 的配置文件位于其安装目录下 /QIBM/STAF/bin,名称为 STAF.cfg。当然,用户也可以根据实际的需要,自己指定配置文件,比如位于 test 目录下的 STAFTest.cfg 文件。 此时,启动 STAF 时,需要指明具体的配置文件,命令如下所示 :STAFProc & /test/STAFTest.cfg。另外,STAF 默认的 SHELL 是 /bin/sh。如果在 STAF 中要使用 QSH,则需要在 STAF 配置文件中增加如下设置语句。SET DEFAULTSHELL "/QOpenSys/usr/bin/qsh -c %C"
STAX 的安装 / 配置
STAX 的安装文件也可以从 STAF 的网站下载。下载完 STAX 后,将其解压到 /QIBM/STAF/services/stax 目录中,然后更改位于 /QIBM/STAF/bin 目录下的配置文件 STAF.cfg。在 STAF.cfg 文件末尾加上如下的代码,然后重启 STAF。如代码 4 所示。
代码 4. 加载服务
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
代码 SERVICE STAX LIBRARY JSTAF EXECUTE {STAF/Config/STAFRoot}/services/stax/STAX.jar
通知 STAF 在启动时以名字 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 能够正确运行。
STAF/STAX 在绿屏上的操作
Process 服务是 STAF 提供的一个内部服务,通过 Process 服务,STAF 可以执行启动、停止以及查询等进程相关的操作。通过 STAF 操作绿屏上的 CL 命令的时候,需要指定命令为 SYSTEM,然后加上 PARMS 关键字。操作 SHELL 命令的时候,需要指定执行 SHELL 命令。接下来,举两个简单的例子,一个是通过 STAF 运行 CL 命令,另一个是通过 STAF 运行 SHELL 命令。
如代码 5 所示。通过 STAF 在 IBM i 上创建一个库 。
代码 5. 创建 Library 示例代码
STAF LOCAL PROCESS START COMMAND SYSTEM PARMS "CRTLIB testlib" WAIT RETURNSTDOUT STDERRTOSTDOUT
执行此命令后 , 将会得到如下的输出。
Response -------- { Return Code: 0 Key : <None> Files : [ { Return Code: 0 Data : CPC2102: Library TESTLIB created. } ] }
Library TESTLIB 创建成功。
如代码 6 所示。通过 STAF 在 IBM i 上创建一个文件夹。
代码 6. 创建文件夹示例代码
STAF LOCAL PROCESS START SHELL COMMAND “mkdir -p /test/backup" WAIT RETURNSTDOUT STDERRTOSTDOUT
执行此命令后 , 将会得到如下所示的输出。
Response -------- { Return Code: 0 Key : <None> Files : [ { Return Code: 0 Data : } ] }
Return Code 是 0,表明操作执行成功。
这里,可以把 mkdir 换成任何一个 SHELL COMMAND。
STAF/STAX 在绿屏上的操作技巧
绿屏上的有些 CL 命令是线程不安全的或者不支持在多线程的作业下运行,当用 STAF 运行这类命令时,直接运行会报错。此时,需要通过 SBMJOB 来提交此命令到后台运行。下面给出一个使用 RSTLICPGM 命令的例子,如代码 7 所示。
代码 7. 运行 RSTLICPGM 示例代码
STAF LOCAL PROCESS START COMMAND SYSTEM PARMS “RSTLICPGM LICPGM(5733l85) OPTION(1) DEV(*SAVF) SAVF(l8530912p/qnotesap) LNG(2924)” WAIT RETURNSTDOUT STDERRTOSTDOUT
因为 RSTLICPGM 不支持在多线程的作业中运行,所以 STAF 命令会运行出错,错误信息如下所示。
CPF3281: New format H created for file H. CPF3292: File H in library QNOTESAPI restored. CPF4380: Open attributes not valid in a multithreaded job. CPF3794: Save or restore operation ended unsuccessfully. CPD3DC3: Product 5733L85 option 1 release *FIRST processing not complete. CPD3DFD: *PGM objects for product 5733L85 option 1 release *FIRST not restored. CPF3D96: Objects for product 5733L85 option 1 release *FIRST not restored.
此时,需要使用 SBMJOB 来提交此命令,如代码 8 所示。
代码 8. 提交 Job 示例代码
STAF LOCAL PROCESS START COMMAND SYSTEM PARMS “SBMJOB CMD(RSTLICPGM LICPGM(5733L85) OPTION(1) DEV(*SAVF) SAVF(L8530912P/QNOTESAP) LNG(2924))” WAIT RETURNSTDOUT STDERRTOSTDOUT
STAF 在绿屏上运行 JAVA 类时,需要在 STAFEnv.sh 里增加 PATH 环境变量的设置。这点
很重要,因为 STAF 在运行时,不读取当前会话的 PATH 变量,而是读取自己启动时设置的 PATH 变量。另外,在绿屏上,通过 STAF 运行 JAVA 类时,需要在命令行加 -Djava.library.path,不能通过设置 LIBPATH 变量来代替此命令行参数。下面给出一个示例,通过 STAF 运行 JAVA 类时,JAVA 调用了 Domino 提供的一个 Notes.jar,如代码 9 所示。
代码 9. 运行 Java 示例代码
STAF LOCAL PROCESS START SHELL WAIT RETURNSTDOUT STDERRTOSTDOUT WORKDIR "/afiseries/auto" COMMAND java PARMS "-Djava.library.path=/qibm/proddata/lotus/domino853 -cp .:/QIBM/ProdData/Lotus/domino853/Notes.jar FrmwrkServVersion"
有些时候,通过 STAF 运行一些 CL 命令时,得到的输出不同于直接在绿屏上运行此命令。例如,在绿屏上通过 RUNDOMCMD 调用 Domino 的 DESIGN 程序时,用 STAF 执行和直接在绿屏上执行,输出的结果就不同。直接在绿屏上执行时,输出结果如图 4 所示,
图 4. 运行 Design 的结果
通过 STAF 执行,如代码 10 所示。
代码 10. 调用 Design 示例代码
STAF LOCAL PROCESS START WAIT RETURNSTDOUT STDERRTOSTDOUT COMMAND SYSTEM PARMS "RUNDOMCMD SERVER(afiseries) CMD(CALL PGM(QDOMINO853/DESIGN)) BATCH(*NO)"
将会得到如下的结果
Response -------- { Return Code: 255 Key : <None> Files : [ { Return Code: 0 Data : } ] }
使用 STAF 不能够得到 DESIGN 程序运行的输出结果。如果用户需要得到输出,则需要将上述命令中的 BATCH 参数设置为 *YES,然后再运行命令,这样输出结果会被写到 Domino 服务器的 console.log 文件里,用户可以通过读取此文件获取输出。对于这样的命令,使用时需要注意。
一些需要和用户进行交互的 CL 命令,不能通过 STAF 直接运行。如果需要通过 STAF 运行该类 CL 命令,要避免命令运行时的交互操作。例如,在运行 RSTLICPGM 命令第一次安装某个许可程序的过程中,需要用户按 F14 键接受软件的许可证以进一步安装。直接使用 STAF 无法在运行 RSTLICPGM 命令的时候实现交互以接受软件许可证。这时候可以先执行 QSYS/QLPACAGR 程序或调用 QPLACAGR API 来预先接受软件许可证,然后再运行 RSTLICPGM 来安装许可程序。如代码 11 所示
代码 11. 接受许可示例代码
CALL PGM(QSYS/QLPACAGR) PARM('5733L85' 'V8R5M3' '0013' X'00000010000000000000000000000000') RSTLICPGM LICPGM(5733L85) OPTION(13) DEV(*SAVF) SAVF(L8530829P/QNOTESRL)
注意:这样的两条 CL 命令需要在同一会话里面运行才能通过调用 QLPACAGR 来代替用户获取许可证的操作,完成正常的安装。然而,STAF 不能直接运行两条 CL 命令,因此我们需要创建一个 CL 程序或者 C 程序来同时完成这两步操作,如代码 12 所示。所创建的 RSTDOM 程序放在库 RSTLIB 下面。
代码 12. 创建 PGM 实现 Domino 安装示例代码
int main(void) { char command[1024]; sprintf(command, "CALL PGM(QSYS/QLPACAGR) PARM('5733L85' 'V8R5M3' '0013' \ X'00000010000000000000000000000000')"); system(command); sprintf(command,"RSTLICPGM LICPGM(5733L85) OPTION(13) DEV(*SAVF) SAVF(L8530829P/QNOTESRL)"); system(command); return 0; }
然后通过 STAF 调用这个程序。如代码 13 所示。
代码 13. 调用 PGM 示例代码
STAF LOCAL PROCESS START COMMAND SYSTEM PARMS “SBMJOB CMD(CALL PGM(RSTLIB/RSTDOM))” WAIT RETURNSTDOUT STDERRTOSTDOUT
这样,通过 STAF 完成了对于需要与用户有交互的 CL 命令的调用。
基于 STAF/STAX 的自动化测试框架
自动化测试框架
接下来介绍一个基于 STAF/STAX 的自动化测试框架,如图 4 所示。该框架已经被应用到了 IBM i 上的一些产品测试中,并且取得了良好的测试效果,大大的提高了测试效率。
图 5. STAF/STAX 的测试框架
如图 5 所示,该框架中包含五个组件。CVS Server,是进行版本控制的工具。在此框架中,使用 RFT(Rational Functional Tester) 实现了具体的测试用例,这些实现脚本通过 CVS 进行版本控制。Control Center 会根据测试人员提交的测试任务,来决定是否需要到 CVS Server 上获取最新
的 RFT 脚本的源代码。Control Center 是内部开发的一个基于 STAF/STAX 的测试框架,它提供了如下功能:
- 提供基于 web 的图形化操作界面给测试人员;
- 提供良好的接口运行基于 STAF/STAX 的测试;
- 可以方便的创建一个测试任务,每个测试任务对应了一个 STAX 脚本文件,在 STAX 脚本中,我们根据不同的业务需求,定义了具体的测试流程;
- 可以实时监控测试的进度;
- 可以把自动化测试执行的日志以更加清晰的形式展现给测试人员;
在采用该自动化测试框架时,用户可以根据实际需要来自定义开发 Control Center。Build Server,是产品 build 的服务器,该服务器上装有 STAF。Control Center 会根据测试人员的设置,来决定是否需要到 build server 上下载指定的 build。Test Client,装有 RFT 和 STAF,是实际运行 RFT 脚本的地方,Control Center 会根据具体的测试任务,发送最新编译、打包好的源代码到测试客户端上,然后在该客户端上完成启动 RFT、运行测试用例等一系列操作。Test Target,是装有 STAF 的 IBM i 系统,也是具体执行测试用例的地方。接收从测试客户端发来的请求,在该 IBM i 机器上执行具体的测试用例。
该测试框架通过 STAF 建立了一个对等的测试环境,任意组件之间可以跨平台的互相访问,互相操作。在此测试环境的基础上,再通过 STAX 脚本来定义具体的测试流程,以及每一步需要完成的具体操作。在该测试框架中,用户可以根据实际业务需求,嵌入任何可以通过命令行方式访问的测试工具。这样,一个跨平台的、可扩展的自动化测试环境就建立起来了。具体的操作流程如下描述。
- 测试人员访问 Control Center,新建或者选择一个已有的测试任务,然后提交该测试任务。在这里,每个测试任务对应了一个 STAX 脚本,在该 STAX 脚本中,描述了具体的测试场景。
- Control Center 会根据测试人员提交的任务所对应的 STAX 脚本,一步一步去执行,首先,它会根据测试人员的设置,到指定的 Build Server 上去获取指定的 Build。
- 将指定的 Build 传到指定的 IBM i 测试机器上。
- 按照 STAX 脚本中定义的流程,发送请求给 CVS Server,获取最新的 RFT 脚本的源代码。
- 在 Control Center 所在的机器上,装有 ant,通过 build 文件编译打包该源代码。
- 将编译打包好的源代码传到指定的测试客户端,启动客户端的 RFT,运行该源代码。
- 测试客户端会根据 RFT 脚本中的设置,访问具体的 IBM i 的机器,然后用该机器上刚下载下来的指定的 build 执行相应的测试工作。
- 测试执行后,会生成测试报告发送给 Control Center,测试用户可以方便的查看测试结果。
按照如上的流程,我们完成了从 Build 下载到生成最终测试报告的自动化测试过程。
测试框架的功能特性
通过前面介绍的自动化测试框架,我们可以看出该框架具有如下的功能特性。
- 可扩展性强,可以根据实际测试需求,将对应的测试工具嵌入到框架中;
- 方便、灵活的操作;
- 平台无关,可以在任何平台上进行测试工作;
- 测试用例和测试框架相分离,真正做到即插即用;
- 实时监控测试任务,方便查看测试日志;
产品中的应用
下面介绍一下该框架在 IBM i 上实际产品测试过程中的应用,以供参考。
首先提交 task,如图 6 所示,当前用户提交了 GetBuild 的任务,该任务需要五个参数。需要指定 Build Server,Test Target,Build 的名称,访问 Build Server 的用户名、密码。
图 6. 测试任务参数设置
执行相应的 STAX 脚本。如代码 14 所示,该 STAX 脚本描述了这样的测试场景,先通过测试人员设置的用户名、密码去访问指定的 Build Server,然后在 Build Server 上检查需要下载的 Build 是否存在,如果不存在,直接返回失败信息;否则,下载指定的 Build 到 Test Target 上,检查 Build 是否下载成功,返回相应的日志信息。STAF 为机器之间的相互访问提供了坚实的基础,STAX 在 STAF 的基础上,通过脚本的方式定义了一系列的测试流程,帮助用户完成具体的测试场景。
代码 14. 获取 Build 示例代码
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE stax SYSTEM "stax.dtd"> <stax> <defaultcall function="GetBuild"></defaultcall> <function name="GetBuild" scope="global"> <function-prolog> This function runs how to get build < /function-prolog> <function-epilog> <![CDATA[ <P>read user input and change it to the library name based on some rules</P> <P>check the library whether exists on build machine</P> <P>get the specified library from the build machine</P> ]]> </function-epilog> <function-list-args> <function-required-arg name="bldsvr"></function-required-arg> <function-required-arg name="target"></function-required-arg> <function-required-arg name="libname"></function-required-arg> <function-required-arg name="user"></function-required-arg> <function-required-arg name="pwd"></function-required-arg> </function-list-args> <sequence> <!--check build--> <log level="'info'">'check library %s exist or not on %s' %(libname,bldsvr)</log> <call function="'CheckBld'">bldsvr,libname</call> <script>(callRC,callResult) = STAXResult</script> <if expr="0 != callRC"> <sequence> <!-- failed to find lib --> <log level="'fail'">' %s: Failed to find lib %s on %s' %(STAXCurrentFunction,libname,bldsvr)</log> <throw exception="'eTerminateFunction'">'lib %s could not be found on %s '%(libname,bldsvr)</throw> </sequence> </if> <log level="'info'">'user %s will get library %s from %s to %s' %(user,libname,bldsvr,target)</log> <sequence> #get specified library from build server #check library download successfully or not </sequence> </sequence> </function> </stax>
STAX 脚本里可以定义一个或者多个 Function,但是必须有一个 Main Function。如上代码所示,Function 通过 name 可以被其他的 STAX 脚本调用,function-prolog 节点定义了该 Function 实现任务的基本描述,function-epilog 节点提供了任务的更详细的描述,比如调用该 Function 前提条件,支持哪些操作系统等,function-list-args 定义了 Function 所需的参数。sequence 节点定义了具体的测试操作流程,每一步执行的命令。当在 Function 中按顺序执行的节点不止一个时,必须使用 sequence。STAX 脚本的详细介绍大家可以参考 STAF 官方网站上的 STAX Service User ’ s Guide。
最后,查看日志信息。STAX 为用户提供了三种类型的日志:STAX 服务日志、作业日志、作业用户日志。STAX 作业用户日志是最详细的用户操作日志,它详细的记录了每一步测试的操作及执行结果。通过调用 STAF 的一个外部服务 - 日志服务,可以查看 STAX 作业用户日志。命令如下所示。
STAF HOSTNAME LOG QUERY MACHINE <Machine Nickname> LOGNAME STAX_JOB_USER
命令中斜体标示的参数可以根据实际的值来设置。日志信息如图 7 所示。
图 7. STAX 作业用户日志信息
这些日志信息是用户在 STAX 脚本中定义的 LOG 节点信息。如上述 STAX 脚本中,第一条 LOG 节点信息,<log level="'info'">'check library %s exist or not on %s' %(libname,bldsvr)</log>
总结
STAF 提供了强大的、扩展性强的自动化开发框架,STAX 作为 STAF 的一个外部服务,为开发流程化的测试脚本提供了强大的支持。二者有效的结合,为 IBM i 平台上的自动化测试提供了良好的解决方案。使用基于 STAF/STAX 的自动化测试框架,可以大大加速开发部署自动化测试的过程、提高测试效率。希望通过本文的介绍,能对准备或者正在 IBM i 上进行自动化测试的同仁们提供些许帮助。
参考资料
学习
- “STAF 官方网站”提供了最新的 STAF 信息及帮助。
- 查看文章“ 利用 STAF 实现程序更新包的自动部署测试
- IBM developerWorks 中国 IBM i 专区 专区:提供给 IBM i 用户和开发者的专业技术资源。
获得产品和技术
- 最受欢迎的 WebSphere 试用软件下载:下载关键 WebSphere 产品的免费试用版。
- IBM developerWorks 软件下载资源中心:IBM deveperWorks 最新的软件下载。
- IBM developerWorks 工具包:下载关键 WebSphere 最新的产品工具包。