STAF/STAX 是由 IBM 開發的自動化測試運行環境,由于其跨平臺和擴展性強的特點,在各種測試工作中被越來越多的使用,但是它也存在流程復雜,操作不便等缺點。而 LAMP 是基于Linux,Apache,MySQL 和 PHP 的開源網絡開發平臺,PHP 可用 Perl 或 Python 代替。Linux+Apache+MySQL+Perl/PHP/Python 常被放在一起使用,來搭建動態網站或者服務器的開源軟件,他們擁有了越來越高的兼容度,共同組成了一個強大的 Web 應用程序平臺。LAMP 具有搭建快捷,界面友好等特點。為了提高測試運行效率,提供良好的使用體驗,我們開發了基于LAMP+STAF/STAX 的自動化測試框架并應用在 WVS 產品的測試中。該框架中前端是 LAMP 實現的動態網站,后端是 STAF/STAX 服務及腳本。我們還利用 STAF 的參數導入特性實現了多任務的自動執行。本文將對基于 LAMP+STAF/STAX 的自動化測試框架的功能特性,體系結構,以及應用在WVS 產品測試中的拓撲結構,設計實現和配置使用進行介紹和分析。
功能特性
該框架不僅利用了 STAF/STAX 的自動化功能,還利用了 LAMP 的強大 Web 應用能力,提供了豐富的自動化測試功能和可擴展特性?傮w來說,主要有以下功能特性:
- 上層應用邏輯和底層自動測試實現松耦合
- 自動化測試功能可擴展性強,支持多任務執行
- 支持遠程程序調用
- 方便友好提交測試任務
- 可實時監控測試任務和 STAX 運行情況
- 歷史測試記錄可維護
![]() ![]() |
![]()
|
體系結構
該框架符合 MVC 的三層結構,主要的功能模塊都在控制層,包括提交和監控測試任務,監控 STAX 運行,支持多任務執行,維護歷史測試記錄等。在該框架中,表示層和控制層的功能實現是以 PHP 形式存在,采用 MySQL 作為數據容器,Apache Server 作為 Web Server,另外在控制層中關于自動化測試的功能實現是以 xml 形式存在,它是被實現層中的 STAF/STAX 所調用。它的體系結構如下圖所示:
圖 1. LAMP+STAF/STAX測試框架結構圖

拓撲結構
我們把該框架應用在了 WVS 產品的自動化測試中,在這個測試中,我們需要更改 WVS 的配置并對其進行重啟,執行 Tester 機器上的腳本,向 Voice Enabler 所在的機器發送 Sip 請求,然后 Voice Enabler 會建立與 WVS 機器的 RTSP 連接以獲取其語音識別和語音合成服務,測試結束后再從 WVS 機器拷貝日志進行分析。我們希望這一切都用 STAF/STAX 控制自動完成。因此在所有的機器上都安裝了 STAF。另外我們把對測試進行前端控制的 LAMP 軟件和代碼也配置在了 Tester 機器上,以充分利用其系統資源。對應的,Tester 機器的 STAF 需要安裝 STAX 服務來運行本地的 STAX 腳本。該系統的部署圖如下所示:
圖 2. LAMP+STAF/STAX 網絡拓撲

![]() ![]() |
![]()
|
設計實現
關于 LAMP 的部分,這里會給出一些應用示圖和代碼示例,關于 STAF/STAX 中的一些功能給出代碼示例,僅供參考。
提交測試任務:
該應用提供了 GUI 方式的任務提交,在提交表單中可以選擇平臺,版本信息,需要運行的用例類型,任務的名字等,方便快捷。如下圖所示
圖 3. 提交測試任務頁面

維護歷史測試記錄:
該應用中的測試記錄都被存儲在了 MySQL 數據庫中,可以進行瀏覽,查詢,刪除等操作,方便測試者察看以前的測試信息,輔以參考。如下圖所示。
圖 4. 任務列表查看頁面

多任務支持:
如前所述,測試任務的執行是由 STAX 模塊來完成的。本框架應用中的 STAX 執行模塊包括三個主要的 STAX 腳本文件,分別是 queuemgr.xml,testexecute.xml 和 funcdef.xml。其中 funcdef.xml 定義了 testexecute.xml 中要用到的功能函數,如判斷操作系統類型和版本、讀寫文件、啟動或停止應用服務器和發送HTTP請求等。testexecute.xml 里定義了測試執行的流程和各種測試變量,它執行時會首先導入記錄了當前測試任務的參數的 xml 文件,然后用這些參數初始化各種測試變量并執行相應測試功能,最后在測試任務完成時將任務參數文件轉移到測試日志所在目錄。queuemgr.xml 定義了一個獨立的 STAX 隊列管理任務,它在啟動后循環檢查測試任務參數文件所在的目錄,如果目錄非空,則選擇最早的任務文件名作為運行參數讓 STAX 執行 testexecute.xml。此外,它還負責測試計時、錯誤處理和延時等待等工作。其運行流程如下圖。
圖 5. 任務列表處理流程

下面給出了 queuemgr.xml 中定義的函數 check-queue 的代碼。它被 queuemgr.xml 的 main 函數在初始化各種全局變量后調用。實現自動執行任務隊列的 STAX 腳本代碼如下。
清單 1. queuemgr.xml 中的 check-queue 函數
<function name="check-queue"> <sequence> <block name="'Queue Manager'"> <sequence> <stafcmd name="'Check Queue'"> <location>'local'</location> <service>'FS'</service> <request>'LIST DIRECTORY %s TYPE F SORTBYNAME' % queueDir</request> </stafcmd> <script>dirList = STAFResult</script> <script>taskCount = len(dirList)</script> <script> if (taskCount != 0): # skip an empty list taskParam = dirList[0] # get first entry else: taskParam = "empty" </script> <if expr=" taskParam != 'empty'"> <if expr=" lastTaskParam != taskParam"> <sequence> <if expr="TestRunInProgress[0] == 0"> <script> TestRunInProgress[0] = 1 TestRunStartTime[0] = now() </script> </if> <script>TestRunCtr[0] = TestRunCtr[0] + 1</script> <script> lastTaskParam = taskParam </script> <script>lastTaskParamJobID = taskParamJobID </script> <log>'QueueMgr: Executing taskParam %s' %(taskParam)</log> <stafcmd name="'Executing Task: %s' % taskParam"> <location>'local'</location> <service>'STAX'</service> <request>'EXECUTE FILE %s CLEARLOGS JOBNAME %s SCRIPT. " taskParam=\'%s\'" WAIT %s' %(TestExecuteFile, taskParam, taskParam,gblTestExecutionTimeoutMS)</request> </stafcmd> <script> taskParamJobID = STAFResult</script> <log>'QueueMgr: taskParam %s JobID = %s' %( taskParam, taskParamJobID)</log> <if expr="RC != STAFRC.Ok"> <sequence> <log>'QueueMgr: Execute Test with Param File %s failed - RC: %s STAFResult: %s' %( taskParam,RC,STAFResult)</log> <terminate block="'main'"/> </sequence> </if> </sequence> <else> <sequence> <log>'QueueMgr: *** TERMINATING Queue Manager *** Task File %s is the same as the last one' %( taskParam)</log> <log>'QueueMgr: Please check the completion status of Test Record %s Job ID %s and Re-Start the Queue Manager' %( lastTaskParam, lastTaskParamJobID)</log> <terminate block="'main'"/> </sequence> </else> </if> <else> <sequence> <if expr="TestRunInProgress[0] == 1"> <sequence> <script> TestRunInProgress[0] = 0 TestRunStopTime[0] = now() testTime = (TestRunStopTime[0] - TestRunStartTime[0]) testHrs = int((testTime) / 3600) testMin = int((testTime - (testHrs * 3600)) / 60) testSec = int((testTime - (testHrs * 3600)) - (testMin * 60)) TestRunCompletionDateTime = strftime('%a %b %d %Y %H:%M:%S', localtime()) </script> <log>'All tests have been run; the testqueue is empty'</log> <log>'Test Run Completed: %s' % TestRunCompletionDateTime</log> <log>'%d Test Tasks Were Completed In %d Hrs %d Min %d Sec' % (TestRunCtr[0],testHrs,testMin,testSec)</log> <script>TestRunCtr[0] = 0</script> <terminate block="'main'"/> </sequence> </if> <block name="'Queue Check Delay'"> <stafcmd name="'Checking TestQueue Every 5000 Sec' % gblCheckQueueDelayTimeSec"> <location>'local'</location> <service>'DELAY'</service> <request>'DELAY 5000'</request> </stafcmd> </block> </sequence> </else> </if> <block name="'Queue Process Delay'"> <stafcmd name="'Checking TestQueue 5000 Sec After Last Task'"> <location>'local'</location> <service>'DELAY'</service> <request>'DELAY 5000'</request> </stafcmd> </block> </sequence> </block> </sequence></function> |
代碼中第一個延時等待是對空任務隊列的查看周期。測試執行人員根據個人習慣有時候希望先啟動任務隊列執行任務,再生成測試任務參數文件。這時查看隊列的循環不能在第一次遇到隊列為空時就退出,而是要不斷反復查看任務隊列。如果在循環之間不加延時,會造成進程對 CPU 開銷過大,影響其他進程。第二個延時是前后兩個測試任務執行之間的延時。這是為了讓剛結束的測試進程有足夠時間釋放各種資源和執行多個文件操作,如日志文件和測試參數文件的轉移。
每次循環中獲得測試任務文件列表時要判斷第一個任務參數文件是否在上次循環中已經嘗試執行過。若是,則上次任務肯定沒有正常結束,否則應該將該任務文件轉移到任務結果文件夾中。這時應該中止任務隊列處理進程,提示測試執行人員查看 STAX 日志排除錯誤。
生成任務參數文件并啟動任務隊列執行的 PHP 代碼如下。該部分代碼在測試者提交了圖 3 所示的測試任務配置表單后執行。
清單 2. 生成任務參數文件并啟動任務隊列的代碼
$isTestStarted = false;$testQueueDir=opendir("$testQueuePath"); while($fileName=readdir($testQueueDir)){ if ($fileName!="." and $fileName!="..") { $isTestStarted = true; break; }}//Here should be the code to create a parameter file for this task, using parameters setby user from the web UI.if(!$isTestStarted){ exec("STAF local STAX EXECUTE FILE /usr/local/staf/xml/queuemanager.xml CLEARLOGS");}header('Location: / viewTestList.PHP'); |
在這里我們并沒有去檢查任務處理進程是否在系統中存在,而是根據任務文件文件夾是否為空來判斷。這一判斷是基于若隊列中有未執行完的任務,則應該有隊列處理進程在進行處理的簡單假設。當然偶爾也會有測試任務出錯,任務處理進程非正常中止的情況發生,使得該假設失準。因此,我們要在 PHP 代碼中查詢任務處理進程的日志,判斷其運行狀態,并在頁面中向測試執行人員顯示出來。如果任務文件夾中尚有文件未執行,而隊列處理進程又處于停止狀態,就要提示測試人員排查錯誤并手動重啟任務隊列處理進程。
STAX 任務啟動后,我們也可以隨時讓 PHP 代碼執行exec("STAF local STAX TERMINATE JOB $JobID")
來中止任務編號為 JobID 的 STAX 任務。
監控 STAX 運行情況:
STAX 一旦出錯,意味著任務無法運行,如果能夠實時監控 STAX 任務運行狀態,可提高可靠性。
清單 3. 監控 STAX 任務狀態
exec("./viewStaxLog.sh $staxJobID 2>&1", $outPut);$isStopped = false;foreach($outPut as $outputline){ $pos = strpos($outputline, "Stop JobID:"); if($pos !== false){ $isStopped = true; }}if($isStopped){ echo "<fond color=\"blue\">Stopped</font><br>";}else{ echo "<fond color=\"red\">Running</font><br>";} |
上面清單中調用了查看 STAX 日志的 shell 腳本。STAX 日志分為兩種,一種是系統對任務運行情況和錯誤的自動記錄,另一種是測試開發人員在 STAX 任務腳本中用 <log></log> 標簽主動記錄的日志?梢酝ㄟ^ STAF 命令實時查詢任何 STAX 任務的日志。在獲得日志后可以根據日志中的關鍵字(如上面代碼中的“Stop JobID:
”)判斷 STAX 任務的狀態。
STAX 的日志可以用 STAF 命令進行查詢,其代碼如下。
清單 4. 查詢 STAX 日志
if [ $1 = “user” ]thenstaf local log query machine mytest.cn.ibm.com logname STAX_Job_$2_Userelsestaf local log query machine mytest.cn.ibm.com logname STAX_Job_$1fi |
遠程程序調用:
在測試過程中,可以讓 STAX 遠程執行要運行的程序,這里給出實際應用中經常會調用 shell 腳本的示例,其 STAX 代碼如下。
清單 5. STAX 遠程調用 shell 腳本
<process> <location>'local'</location> <command mode="'shell'" >'"./%" result %s %s' % (testScriptName,testParam1,testParam2)</command> <workdir>'%s' % testScriptDir</workdir> <stderr mode="'stdout'"/> <returnstdout/></process><if expr="RC != 0"> <log>'Error: RC=%s, STAXResult=%s, Error running test script' % (RC, STAXResult)</log> <else> <log>'Running test script. STAXResult=%s' % (STAXResult)</log> </else></if> |
分析測試結果:
STAX 使用 Python 處理其腳本中的表達式。為了便于文本分析,使用者可以在 STAX 腳本中嵌入 Python 腳本。用這種方式可以方便地利用 Python 強大的正則表達式處理能力。下面的代碼示范如何從日志文件中提取相關文字并進行對比判斷。
<stafcmd> <location>'%s' % logServer</location> <service>'fileman'</service> <request>'grep file "%s" machine "%s" for "%s" last CODEPAGE ascii' % (testLogName,logServer,testCaseName)</request></stafcmd><!—- Some other code here --><script> import re import string result = str(STAFResult[0]) testCaseMatch = re.search("%s %s" % (testCaseName.upper(),expectedResult.upper()),result.upper())</script> |
配置使用
配置這樣一個自動化測試框架,需要安裝 Apache Server,MySQL,PHP,如何安裝該環境,這里就不贅述。我們開發的測試框架由于其功能比較多,也需要在測試中不斷的更改配置,有時還要增加測試內容。為了便于其配置,我們將PHP代碼中有可能需要修改的變量都放在一個單獨的 PHP 文件中,而與測試用例相關的變量用 PHP 數組的形式存放在另一個 PHP 文件中。所有要用到這些配置的 PHP 文件對其進行包含。
總結
LAMP 是功能強大的 Web 應用程序平臺,STAF/STAX 具有很好的自動測試功能,把二者結合起來就可以形成更加靈活可靠,易于功能擴展的新的自動化測試框架,本文也通過在 WVS 產品測試中使用該框架從而獲得了很好的測試效果。
文章來源于領測軟件測試網 http://www.kjueaiud.com/