乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      使用 CruiseControl 和 STAF 建立復(fù)雜環(huán)境下的編譯和測試自動化

       gyb98 2011-03-30

      使用 CruiseControl 和 STAF 建立復(fù)雜環(huán)境下的編譯和測試自動化

      崔 俊濤 (cuijunt@cn.ibm.com), 軟件工程師, IBM
      費 伽 (feijia@cn.ibm.com), 軟件工程師
      陳 頡 (chenjieee@hotmail.com), 軟件工程師

      簡介: 本文結(jié)合 CruiseControl 和 STAF (STAX) 實現(xiàn)在復(fù)雜環(huán)境下的持續(xù)集成和自動化編譯測試。在我們的解決方案中,CruiseControl 充當(dāng)入口來定時觸發(fā)編譯和測試的過程。在更新完 CVS 代碼后,CruiseControl 調(diào)用 STAX 任務(wù)來對代碼進(jìn)行分發(fā)、編譯、部署、測試以及收集日志,最后日志會被集成到 CruiseControl 的控制臺,用來顯示給開發(fā)和測試人員。本文提出的測試方案不僅能夠減輕測試人員的工作量,而且能夠把測試結(jié)果及時反饋給開發(fā)人員,增強(qiáng)他們在開發(fā)過程中的信心。

      發(fā)布日期: 2008 年 2 月 14 日 
      級別: 初級 
      訪問情況 779 次瀏覽 
      建議: 0 (添加評論)

      1 star2 stars3 stars4 stars5 stars 平均分 (共 1 個評分 )

      介紹

      持續(xù)集成能夠使開發(fā)人員和測試人員在同一個最新的版本上工作。CruiseControl 是現(xiàn)在流行的持續(xù)集成的軟件。自動化測試能夠大大減輕測試人員的工作量,減少測試過程中人為出現(xiàn)的錯誤。STAF (STAX) 是一個輕量級的自動化測試框架。

      本文結(jié)合 CruiseControl 和 STAF (STAX) 來介紹一個復(fù)雜環(huán)境下的自動化測試方案。我們使用 CruiseControl 作為自動化測試的入口和調(diào)度器,用它來控制 STAX 任務(wù)的執(zhí)行。STAX 通過 STAX 復(fù)雜對測試代碼進(jìn)行分發(fā)、編譯、部署和測試。在整個測試過程中,我們不僅可以使用 JUnit 測試用例來測試代碼,而且可以使用其他方式的測試用例來測試,比如 Rational Functional Tester 腳本,Robot 腳本等。

      場景介紹

      本文使用一個簡化了的復(fù)雜應(yīng)用場景作為運(yùn)行自動測試解決方案的環(huán)境。 該應(yīng)用由一個提供簡單 Echo Service 的 WebService 和一個 Web 界面的 WebService 客戶端組成。 用戶既可以使用程序來直接訪問該 WebService 也以通過在瀏覽器中操作該客戶端來訪問 WebService 提供的服務(wù)。在訪問 WebService 和客戶端之前,用戶都需要經(jīng)過身份驗證來聲明自己的身份。

      WebService 和客戶端分別運(yùn)行于 Windows 和 Linux 平臺上的 WebSphere 應(yīng)用服務(wù)器之上。在 WebSphere 應(yīng)用服務(wù)器上需要配置登錄認(rèn)證模塊來實現(xiàn)用戶訪問前的身份認(rèn)證。

      在這一應(yīng)用場景中,測試團(tuán)隊經(jīng)過分析,對自動化功能測試提出了以下需求:

      1. WebService 和客戶端需要分別進(jìn)行功能測試。
      2. 開發(fā)團(tuán)隊提供了用于配置應(yīng)用程序登錄模塊 (LoginModule) 的自動配置部署腳本,該腳本被發(fā)布到一個 FTP 服務(wù)器上。
      3. WebService 和客戶端的源代碼以及測試腳本的源代碼都存放在 CVS 上,需要在測試執(zhí)行前進(jìn)行自動更新。
      4. 自動化測試執(zhí)行需要每天自動定時運(yùn)行。
      5. 測試執(zhí)行的結(jié)果包括執(zhí)行日志需要被測試團(tuán)隊和開發(fā)團(tuán)隊及時訪問到。

      自動化測試方案的設(shè)計

      針對上述需求,我們可以將這一自動化測試方案分隔為如下圖所示的幾個邏輯組件:


      圖 1. 自動化測試方案的邏輯框圖
       

      部署腳本庫是指發(fā)布配置登錄模塊的腳本的服務(wù)器。在本文中,是一個 FTP 服務(wù)器。

      源代碼庫是指發(fā)布被測試應(yīng)用程序源代碼以及測試相關(guān)源代碼的服務(wù)器。在本文中,WebService 和客戶端的源代碼以及測試腳本的源代碼都被發(fā)布在一個 CVS 服務(wù)器上。

      定時器設(shè)置每天特定時間觸發(fā),本文中,定時器的功能是 CruiseControl 提供的。

      自動編譯工具將從源代碼庫中獲取的測試代碼和被測試代碼進(jìn)行編譯。本文中,使用CruiseControl 結(jié)合 Ant 作為自動編譯工具。

      測試自動化框架負(fù)責(zé)將編譯完成的被測試代碼和測試代碼部署到測試環(huán)境中,并調(diào)用測試自動化執(zhí)行工具來執(zhí)行測試。在測試執(zhí)行介紹后,框架還需要收集相應(yīng)的執(zhí)行日志,并將執(zhí)行結(jié)果和日志交由 CruiseControl 進(jìn)行發(fā)布,以供測試和開發(fā)人員參考。在本文中,測試框架采用了開源的 STAF、STAX 框架。

      測試執(zhí)行工具是指進(jìn)行測試的各種測試工具,本文中,測試工具使用了 JUnit,RFT 等。

      測試環(huán)境是指運(yùn)行被測試代碼和測試腳本的環(huán)境。在實際應(yīng)用中測試環(huán)境既可能是一個簡單的Windows 服務(wù)器,也可能是由許多不同平臺,不同類型的服務(wù)器組成的復(fù)雜環(huán)境。本文中,測試環(huán)境包括了不同版本不同平臺的 WebSphere Application Server,以及運(yùn)行測試腳本的一臺服務(wù)器。

      測試報表工具是將測試執(zhí)行結(jié)果和日志進(jìn)行呈現(xiàn)的工具。由于測試過程完全自動進(jìn)行,只有將測試結(jié)果和日志盡可能清晰的展示在測試和開發(fā)人員面前,才能充分發(fā)揮自動測試的作用。

      從上面對各個邏輯組件的描述中可以看出,測試框架在整個自動化測試方案中位于核心位置。它像控制器一樣管控著其他各個組件,同時又像膠水一樣把各個組件連結(jié)起來協(xié)同工作。

      在分析了測試自動化需求和邏輯組件之后,我們可以給出具體的測試方案設(shè)計。


      圖 2. 測試方案設(shè)計實現(xiàn)
       

      在上圖中,

      控制機(jī)上安裝了 CruiseControl 和 STAF、STAX 框架兩套工具。

      編譯機(jī)上安裝了編譯工具 Ant 以及測試執(zhí)行工具 Junit 和 RFT。 其中 JUnit 測試腳本用來測試 WebService,而 RFT 測試腳本則用來測試和操作客戶端。

      測試機(jī) 1 測試機(jī) 2 則分別用來運(yùn)行 WebService 和客戶端。

      該測試方案的具體執(zhí)行步驟如下:

      1. CruiseControl 服務(wù)器在每日指定的時間自動從 CVS 服務(wù)器獲取最新測試代碼,完成后 CruiseControl 服務(wù)器執(zhí)行一個批處理命令來啟動一個 STAF 任務(wù)。
      2. 該 STAF 任務(wù)從 FTP 服務(wù)器下載最新配置登錄模塊的腳本到本地目錄。
      3. STAF 將 WebSerivce 和客戶端的源代碼,測試腳本源代碼,以及測試代碼分發(fā)到編譯機(jī)上。
      4. STAF 在編譯機(jī)上調(diào)用編譯工具 Ant 來編譯被測試代碼(編譯出包含 WebService 的 war 和包含客戶端的 war ),測試腳本源代碼。
      5. STAF 將編譯出的運(yùn)行時代碼 (war) 通過 WAS 遠(yuǎn)程命令部署到測試機(jī)1,2中。
      6. STAF 將配置登錄模塊的腳本發(fā)布到測試機(jī)1,2中,并分別在測試機(jī)上運(yùn)行該腳本來配置登錄模塊。
      7. STAF 在編譯機(jī)上調(diào)用 JUnit 和 RFT 來運(yùn)行測試代碼。
      8. STAF 將測試結(jié)果送回控制機(jī)并顯示。

      使用的產(chǎn)品和技術(shù)

      STAF/STAX

      軟件測試自動化框架( Software Testing Automation Framework,簡稱 STAF )是一個開源的測試自動化框架,它的設(shè)計核心理念是稱為“服務(wù)”的可重用組件(例如,進(jìn)程調(diào)用,資源管理,日志和監(jiān)控等)。 STAX 是構(gòu)建在 STAF,XML 和 Python 語言之上的執(zhí)行引擎,它的出現(xiàn)大大的簡化了測試人員的實現(xiàn)測試自動化的工作。STAX 同時還提供了一個強(qiáng)大的圖形界面監(jiān)控程序,使用該監(jiān)控程序你可以監(jiān)控并控制正在 STAF 框架中執(zhí)行的任務(wù)。

      本文STAF/STAX 腳本一章詳細(xì)介紹了在如何使用 STAF/STAX。

      CruiseControl

      CruiseControl 是一個被廣泛使用的用于軟件持續(xù)集成的開源框架。 所謂軟件的持續(xù)集成( Continuous Integration )是指一種軟件開發(fā)團(tuán)隊頻繁的將他們各自開發(fā)的組件進(jìn)行集成的實踐。通過軟件的持續(xù)集成可以盡早的發(fā)現(xiàn)錯誤,并降低最終集成時所耗費的時間和精力。

      本文配置 CruiseControl 一章詳細(xì)介紹了如何配置和使用 CruiseControl。

      JUnit/HttpUnit

      JUnit 是一個被廣泛使用的用于測試 Java 應(yīng)用程序的開源自動化測試框架。JUnit 提供了十分簡潔易用的編程接口來讓測試人員編寫測試腳本。同時搭配使用 xUnit 系列的工具,JUnit 可以完成對許多不同類型的應(yīng)用的測試。

      HttpUnit 是一個專門針對 Web 應(yīng)用程序進(jìn)行自動化測試的開源類庫。它可以模擬瀏覽器的行為(包括表單提交,JavaScript,簡單 http 認(rèn)證,cookie,以及頁面重定向等)來測試 Web 應(yīng)用程序并且允許測試代碼檢查從服務(wù)器端返回的頁面。

      在本文中,我們搭配使用 JUnit 和 HTTPUnit 這兩個工具來測試 WebService。

      Rational Functional Tester

      IBM Rational Functional Tester ( RFT ) 是一個用于進(jìn)行自動化的功能和回歸測試的工具。它使得測試人員可以測試應(yīng)用程序的圖形界面,并提供了數(shù)據(jù)驅(qū)動的測試能力。 RFT 支持不同平臺上的各種類型的圖形界面應(yīng)用,常見的包括在瀏覽器中運(yùn)行的 Web 應(yīng)用界面,用 SWT 開發(fā)的圖形界面等。不僅如此, RFT 還提供了多種語言版本的測試腳本和開發(fā)環(huán)境供測試人員選擇,包括在 Eclipse 環(huán)境中開發(fā) Java 測試腳本和在微軟的 Visio Studio 環(huán)境中開發(fā) VB.net 腳本。RFT 當(dāng)前最新的版本為 7.0。

      在本文中,我們使用 RFT 來測試 WebService 客戶端。

      準(zhǔn)備環(huán)境

      本章介紹在自動測試前的準(zhǔn)備工作,包括下列內(nèi)容:

      1. 配置 WAS 環(huán)境變量,
      2. 刪除 WAS 上的 JAAS 登錄模塊腳本
      3. WAS 重啟腳本
      4. 在部署服務(wù)器上準(zhǔn)備部署腳本

      配置 WAS 環(huán)境變量 ( WAS_HOME )

      在使用 WAS 開始工作前,首先要配置 WAS 環(huán)境變量 WAS_HOME,WAS_HOME 用于指向 WAS 的安裝目錄。下文中,在使用一些 WAS 自帶的工具時,會引用環(huán)境變量 WAS_HOME 來表示 WAS 的安裝目錄。具體的設(shè)置方法如清單 1 所示。


      清單 1. 配置 WAS_HOME
                      
      [Windows Platform]
      set WAS_HOME=C:\Program Files\IBM\AppServer
      echo %WAS_HOME%
      
      [Linux Platform]
      export WAS_HOME=/opt/IBM/AppServer
      echo $WAS_HOME
      

      清單1展示了如何配置 WAS_HOME。

      在 Windows 平臺中使用 set 命令進(jìn)行設(shè)置,以后可以通過 %WAS_HOME% 進(jìn)行訪問。

      在 Linux 平臺中使用 export 命令進(jìn)行設(shè)置,以后可以通過 $WAS_HOME 進(jìn)行訪問。如果要使環(huán)境變量 WAS_HOME 在系統(tǒng)啟動時自動設(shè)置,可以將 export 語句添加到 boot.local 文件中。

      刪除 WAS 上的 JAAS 登錄模塊腳本

      在正式的測試之前,WAS 上的 JAAS 錄模塊需要更新到最新的版本。為了保證最新版本的成功更新,我們首先要將舊版本的 JAAS 登錄模塊刪除(如果存在的話),如清單 2 所示。


      清單 2. 刪除 JAAS 登錄模塊 – DeleteLoginModule.py
                      
      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 = None
      10     for eachEntry in jaasConfigurationEntrys :
      11         jlmAlias = AdminConfig.showAttribute(eachEntry, "alias")
      12         if jlmAlias == loginModuleAlias :
      13             entry = eachEntry
      14             print "\nEntry found: " + entry
      15             break
      
      16     if entry != None :
      17         AdminConfig.remove(entry)
      18         print "\nEntry deleted: " + entry
      19         AdminConfig.save()
      

      清單 2 展示了如何使用 wsadmin 腳本來刪除 WAS 上的 JAAS 登錄模塊。WAS 的 wsadmin腳本支持 Jacl 和 Jython 兩種類型的腳本語言,這個示例采用了 Jython 語言。

      其中,第 1 行設(shè)置了 loginModuleAlias 變量,用于保存待刪除的 JAAS 登錄模塊的別名。第 2 行定義了 lineSeparator 常量,用于表示換行符。第 3-4 行獲取了 WAS 中的 Cell 列表,并遍歷整個 Cell 列表,對每個 Cell 進(jìn)行處理。第 5-6 行獲取了 Cell 中的安全配置,得到 Application Login Configuration。第 7-8 行進(jìn)一步獲取 Cell 中的 JAAS 登錄模塊的列表。

      第 9 行設(shè)置了 entry 變量,用于保存查找到的待刪除的 JAAS 登錄模塊,初始值設(shè)為 None,表示未找到。

      第 10-15 行是一個循環(huán),遍歷 Cell 中的 JAAS 登錄模塊的列表。對每個 JAAS 登錄模塊,第 11 行首先獲取它的別名,第 12 行將別名與 loginModuleAlias 變量中保存的待刪除的 JAAS 登錄模塊的別名進(jìn)行比較,如果相同則說明這個 JAAS 登錄模塊就是待刪除的登錄模塊。第 13 行將該 JAAS 登錄模塊保存在 entry 變量中,第 14 行打印出找到待刪除登錄模塊的日志信息,第 15 行則退出循環(huán)。如果在循環(huán)沒有找到和待刪除登錄模塊相匹配的,則 entry 變量保持為 None。

      第 16-19 行是刪除登錄模塊的代碼,第 16 行判斷一下是否找到待刪除登錄模塊,如果 entry 變量為 None,則說明沒有找到,直接退出。反之,第 17 行執(zhí)行刪除,第 18 行打印出刪除日志信息,第 19 行保存更改。

      在我們的示例中,刪除 JAAS 登錄模塊腳本是存放在一臺 Linux 系統(tǒng)中,我們要通過這個Linux 系統(tǒng)上的 WAS 來刪除環(huán)境中的其它系統(tǒng)上的 WAS 中的 JAAS 登錄模塊,這個操作需要通過 wsadmin 工具來遠(yuǎn)程訪問其它 WAS。調(diào)用過程如清單 3 所示。


      清單 3. 調(diào)用刪除 JAAS 登錄模塊 – DeleteLoginModule.sh
                      
      01 $WAS_HOME/bin/wsadmin.sh
      02    -conntype SOAP
      03    -host 172.16.0.124
      04    -username wasadmin -password passw0rd
      05    -lang jython
      06    -f DeleteLoginModule.py
      

      清單 3 展示了如何通過 wsadmin 工具調(diào)用刪除 JAAS 登錄模塊的方法。

      第 1 行 $WAS_HOME/bin/wsadmin.sh 為 wsadmin 工具,用于管理 WAS 以及配置、應(yīng)用程序部署和服務(wù)器運(yùn)行時操作。

      第 2 行指定使用的連接方式為 SOAP,連接方式可能的類型包含:SOAP、RMI 和 NONE。第3行指定目標(biāo) WAS 的主機(jī)名。第4行指定用來連接到遠(yuǎn)程 WAS 的用戶名和密碼。第5行指定腳本文件的語言采用 Jython 語言,可能的語言包括: Jacl 和 Jython 。第6行指定在目標(biāo) WAS 上要運(yùn)行的腳本。

      (注:第 1 行到第 6 行為一條完整的命令,此處為講解方便分解成 6 行)

      WAS 重啟腳本

      在更新(安裝或刪除) JAAS 登錄模塊之后,必須重新啟動 WAS,以使更新生效。每個WAS 機(jī)器上都需要準(zhǔn)備重啟的腳本,該腳本在本地運(yùn)行,控制指令通過 STAF/STAX 遠(yuǎn)程發(fā)起。 WAS重啟腳本,如清單 4 所示。


      清單 4. 重啟WAS
                      
      [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。如果啟用了全局安全,則需要設(shè)定連接 WAS 的用戶名和密碼。startServer.sh 用于啟動 WAS。

      在部署服務(wù)器上準(zhǔn)備部署腳本

      在每次測試之前,需要將 WAS 上部署的應(yīng)用程序更新到最新的版本。為了保證最新版本的成功更新,我們首先要將舊版本的應(yīng)用程序刪除(如果存在的話),然后按照新版本的應(yīng)用程序,最后啟動新安裝的應(yīng)用程序。完整的過程如清單 5 所示。


      清單 5. 部署應(yīng)用程序 – UpdateApplication.py
                      
      01 import sys
      
      02 # define uninstall application
      03 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_value
      10         print '[FAIL]'
      11     else:
      12         print '[OK]'
      
      13 # define install application
      14 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_value
      21         print '[FAIL]'
      22     else:
      23         print '[OK]'
      
      24 # define start application
      25 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_value
      33         print '[FAIL]'
      34     else:
      35         print '[OK]'
      
      36 # parse command line arguments
      37 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 application
      45 uninstallApp(appName)
      46 installApp(appName, earFileName)
      47 startApp(appName)
      

      清單 5 展示了如何在 WAS 上重新部署應(yīng)用程序。

      其中,第 1 行導(dǎo)入了系統(tǒng)函數(shù)庫 sys。

      第 2-12 行定義了函數(shù) uninstallApp,用于卸載已安裝的應(yīng)用程序。第 3 行是函數(shù)的聲明,該函數(shù)包含一個參數(shù) appName,即待卸載的應(yīng)用程序名稱。第 4、8、11 行是一個 try…except…else… 的異常處理模塊,用于對卸載過程中發(fā)生的任何異常進(jìn)行處理,并將異常信息返回給用戶。第 6 行執(zhí)行卸載操作,第 7 行保存卸載操作的更改。如果在卸載過程中發(fā)生異常,第 9 行將異常的類型和異常的信息顯示給用戶,第 10 行告知用戶操作失敗。反之,第 12 行告知用戶操作成功。

      第 13-23 行定義了函數(shù) installApp,用于安裝新的應(yīng)用程序。第 14 行是函數(shù)的聲明,該函數(shù)包含兩個參數(shù): appName 為待安裝的應(yīng)用程序名稱, earFileName 為待安裝的EAR包的文件名。第 17 行執(zhí)行安裝操作。其它代碼與函數(shù) uninstallApp 中的相應(yīng)代碼類似。

      第 24-35 行定義了函數(shù) startApp,用于啟動應(yīng)用程序。第 25 行是函數(shù)的聲明,該函數(shù)包含一個參數(shù) appName ,即待啟動的應(yīng)用程序名稱。第 28 行獲取 Application Manager 對象,第 29 行執(zhí)行啟動操作。其它代碼與函數(shù) uninstallApp 中的相應(yīng)代碼類似。

      第 36-43 行解析命令行參數(shù),第一個參數(shù)為應(yīng)用程序名稱,是必須的;第二個參數(shù)為應(yīng)用程序EAR 包的名稱,是可選的,如果省略,則在應(yīng)用程序名稱后加上 ’.ear’ 來代替。

      第 44-47 行更新應(yīng)用程序,首先刪除現(xiàn)有的應(yīng)用程序,然后按照新的應(yīng)用程序,最后啟動新安裝的應(yīng)用程序。

      在我們的示例中,部署應(yīng)用程序腳本是存放在一臺 Linux 系統(tǒng)中,這臺 Linux 系統(tǒng)稱為部署服務(wù)器。我們要通過部署服務(wù)器上的 WAS 來更新環(huán)境中的其它系統(tǒng)上的 WAS 中的應(yīng)用程序。這個調(diào)用過程是通過 wsadmin 工具來完成的,腳本和“調(diào)用刪除 JAAS 登錄模塊”腳本類似,請參見清單 3,此處不再贅述。

      STAF/STAX 腳本

      STAF/STAX 腳本包括以下部分:

      1. 環(huán)境清理
      2. 下載配置 WAS 登錄模塊腳本
      3. 分發(fā)和運(yùn)行配置 WAS 登錄腳本
      4. 重啟 WAS
      5. 復(fù)制源碼到編譯機(jī)
      6. 控制編譯機(jī)編譯源碼
      7. 復(fù)制 WAR 到部署機(jī)器上并部署
      8. 調(diào)用測試代碼
      9. 收集日志

      下面我們分別介紹每個部分的腳本。

      環(huán)境清理

      在進(jìn)行自動化編譯、部署和測試之前,需要對上次測試的環(huán)境進(jìn)行清理,以除去上次測試的殘留,保證測試結(jié)果的正確和合理。首先我們需要調(diào)用第 4 章的 WAS clean 腳本來刪除 WAS 中的登錄模塊。


      清單 6. STAX 調(diào)用 WAS clean 腳本示例
                      
      1 <script> 
      2   machineList = [‘was602_Linux’, ‘was61_Linux’, ‘was602_Windows’, ‘was61_Windows’]
      3 </script>
      4 <paralleliterate var=”machine” in=”machineList”>
      5   <if expr=“machine.find(‘Linux’)>=0 ”>
      6     <sequence>
      7       <stafcmd>
      8         <location> ‘%s’ % machine </location>
      9         <service> ‘process’ </service>
      10        <request> ‘start command "/root/script/CleanupEnv.sh" username "root" password
      11         "password" workdir "/root/script" wait stdout /root/script/cleanupEnv%s.log' 
      12         % machineName
      13        </request>
      14      </stafcmd>
      15    </sequence>
      16  </if>
      17  <if expr=“machine.find(‘Windows)>=0 ”>
      18    <sequence>
      19      <stafcmd>
      20        <location> ‘%s’ % machine </location>
      21        <service> ‘process’ </service>
      22        <request> ‘start command "C:/script/CleanupEnv.bat" username "Administrator" 
      23          password "password" workdir "C:/script" wait stdout 
      24          C:/script/cleanupEnv%s.log' % machineName
      25        </request>
      26      </stafcmd>
      27    </sequence>
      28   </if>
      29 </paralleliterate>
      
      

      在清單 6 中,我們把系統(tǒng)分成了兩套環(huán)境,Windows 系統(tǒng)和 Linux 系統(tǒng),針對于不同的環(huán)境,cleanupEnv 腳本有不同的路徑和后綴名。首先 4-29 行使用了并行的遍歷來分別在各個系統(tǒng)上調(diào)用 cleanupEnv 腳本。在第 5 行和第 17 行中,if 語句使用的 expr 用 python 來解析,因此可以用 python 來寫一些復(fù)雜的比較和判斷語句。find 函數(shù)表示在字符串中查找指定的字符串。

      5-16 行針對于 Linux 的系統(tǒng),使用 root 用戶來調(diào)用 CleanupEnv.sh 腳本。17-28 行針對于Windows 系統(tǒng),使用 Administrator 用戶來調(diào)用 CleanupEnv.bat 腳本。

      CleanupEnv 腳本有兩種儲存方法:

      1. 事先存放在各個測試機(jī)器上
      2. 存放在 CruiseControl 控制機(jī)器上,然后由 STAX 來根據(jù)環(huán)境來分發(fā)這些腳本。

      一般情況下,推薦使用第二種方法。腳本分布在不同的機(jī)器上,如果發(fā)生一點小的改動,極易引起腳本的不同步。使用第二種方法,不僅會避免這個問題,而且只需改動一個腳本,將極大的節(jié)省測試人員的工作量。使用第二種方法只需在第 7 行和第 19 行前面加上 STAF 復(fù)制文件的命令即可。在 Linux 上如下所示:


      清單 7. STAX 分發(fā) CleanupEnv 腳本示例
                      
      <stafcmd>
        <location> ‘%s’ % machine </location>
        <service> ‘fs’ </service>
        <request> ‘copy FILE "D:/sample/CleanupEnv.sh" TODIRECTORY /root/script/’
        </request>
      </stafcmd>
      

      把文件復(fù)制到 Linux 上需要注意一個問題,就是文件的某些屬性可能沒有被復(fù)制,比如可執(zhí)行屬性,因此需要使用下面的命令來更改文件的屬性,以便用戶能夠執(zhí)行此文件。


      清單 8. STAX 更改文件屬性
                      
      <stafcmd>
        <location> ‘%s’ % machine </location>
        <service> ‘process’ </service>
        <request> ‘start command "chmod +x /root/script/CleanupEnv.sh"’
        </request>
      </stafcmd>
      

      下載配置 WAS 登錄模塊腳本

      在刪除上次自動化測試配置的登錄模塊之后,我們需要從 FTP 下載最新版本的配置登錄模塊的腳本。本文使用 Windows 自帶的 FTP 命令來完成腳本的下載。FTP 上存放了不同時期的版本,每個版本使用文件名+時間戳的方式來區(qū)分,而 FTP 命令并沒有提供下載最新腳本的功能,因此我們需要自己來判斷那個腳本是最新的。首先利用 FTP 的 ls 命令來列出所有的版本文件,通過 java 程序來判斷哪個是最新的版本,最后再利用 FTP 命令來下載最新的版本。STAX 腳本如下所示:


      清單 9. 下載最新的版本文件
                      
      <sequence>
      <process>
      <location>'local'</location>
      <command>'ftp'</command>
      <parms>'-s:C:/Sample/ftpconf/ftplist.conf'</parms>
      <workdir>'C:/Sample'</workdir>
      </process>
      
      <process>
      <location>'local'</location>
      <command>'java'</command>
      <parms>'-cp . fileParsing.ParseBuildTime temp.txt ftptemplate.conf 
      ftpdown.conf'</parms>
      <workdir>'C:/Sample'</workdir>
      </process>
      				
      <process>
      <location>'local'</location>
      <command>'ftp'</command>
      <parms>'-s:C:/Sample/ftpconf/ftpdown.conf'</parms>
      <workdir>'C:/Sample'</workdir>
      </process>
      </sequence>
      

      其中第一個 Process 命令從 FTP 服務(wù)器上獲取所有的版本文件信息,保存到 temp.txt 文件中。ParseBuildTime 用來從版本文件列表 temp.txt 中找出最新的版本文件,并且根據(jù)提供的 FTP 模板文件 ftptemplate.conf 生成 FTP 腳本 ftpdown.conf,供 STAX 腳本調(diào)用下載最新的版本文件。第三個 Process 命令調(diào)用 ftpdown.conf 從 FTP 服務(wù)器下載最新的版本文件。

      清單 10 顯示了 FTP 模板文件,它是由一系列 FTP 命令組成。


      清單 10. FTP 模板腳本
                      
      open ftp.ibm.com
      user
      password
      binary
      prompt
      cd /sampledirectory
      lcd C:\Sample\build
      get "<template>" ConfigureLoginModule.zip
      bye
      

      分發(fā)和運(yùn)行配置 WAS 登錄模塊腳本

      本節(jié)把下載的最新版本文件解壓縮后分發(fā)到 WAS 平臺。解壓縮使用 Winrar 命令來進(jìn)行,如下所示:


      清單 11. 使用 Winrar 命令解壓縮
                      
      <process>
      <location>'local'</location>
      <command>'C:\Program Files\winrar\winrar.exe'</command>
      <parms>'x -o+ C:/Sample/build/ConfigureLoginModule.zip'</parms>
      <workdir>'D:/STAFDirectory/build/'</workdir>
      </process>
      

      如何分發(fā)文件和清單 7 類似,這里不再贅述。

      將配置 WAS 登錄模塊腳本分發(fā)完成后,需要調(diào)用它完成 WAS 登錄模塊的配置。調(diào)用腳本的STAX 代碼與清單 6 類似,這里也不再贅述。

      重啟 WAS

      在完成 WAS 登錄模塊配置后,需要重啟 WAS 來使配置生效。這里調(diào)用第三章的 WAS 重啟腳本來完成WAS服務(wù)器的重啟。在調(diào)用 WAS 重啟腳本之前,需要分發(fā)此腳本到每個 WAS 服務(wù)器上。過程類似于清單 6 和清單 7 。有一點不同的是, WAS 重啟腳本可能會需要運(yùn)行較長一段時間,比如 5 分鐘,因此 STAX 命令中的 wait 關(guān)鍵字不能忽略,表示需要等待 WAS 重啟結(jié)束,如下所示:


      清單 12. STAX 重啟 WAS 腳本示例
                      
      <stafcmd>
        <location> ‘%s’ % machine </location>
        <service> ‘process’ </service>
        <request> ‘start command "/root/script/RestartServer.sh" username "root" password
          "password" workdir "/root/script" wait stdout /root/script/RestartServer%s.log' 
         % machineName
        </request>
      </stafcmd>
      

      復(fù)制源碼到編譯機(jī)

      在啟動測試過程之前,CruiseControl 會調(diào)用 Ant 腳本從 CVS 下載最新的源碼,包括 Web Service 源碼、測試代碼和 RFT 代碼。在測試之前,我們需要將它們復(fù)制到編譯機(jī)上進(jìn)行編譯,因為某些代碼需要依賴于 WAS 或者 RFT 平臺。

      復(fù)制代碼分為三個部分:

      1. 復(fù)制 Web Service 源碼(被測試代碼)。
      2. 復(fù)制測試代碼 (Web Service 客戶端以及 JUnit 代碼)
      3. 復(fù)制 RFT 代碼。

      復(fù)制過程和清單 7 類似。

      控制編譯機(jī)編譯源碼

      每個部分的源碼都有 build.xml 文件,所以只需要調(diào)用 Ant 命令來編譯即可。


      清單 13. 編譯源碼
                      
      <stafcmd>
      <location>'%s' % machine</location>
      <service>'process'</service>
      <request>'start command "c:/apache-ant-1.6.5/bin/ant.bat -buildfile %s/build.xml 
      > %s/build.log"  username "Administrator" password "password" workdir %s wait' 
      % (sourceLocation, sourceLocation, sourceLocation)
      </request>
      </stafcmd>
      

      與編譯 Web Service 源碼和測試代碼不同的是, RFT 代碼需要指定 RFT 安裝的位置,這通過傳遞 Ant 參數(shù)來實現(xiàn),如清單 14 所示。


      清單 14. 編譯 RFT 測試腳本
                      
      <stafcmd>
      <location>'%s' % machine </location>
      <service>'process'</service>
      <request>'start command "c:/apache-ant-1.6.5/bin/ant.bat -buildfile %s/buildRFT.xml 
      -DRFTDriver=%s > %s/build.log"  username "Administrator" password "password" 
      workdir %s wait' % (sourceLocation, RFTDriver, sourceLocation, sourceLocation)
      </request>
      </stafcmd>
      

      復(fù)制 WAR 到部署機(jī)器上并部署

      編譯完成后,需要將編譯生成的 WAR 文件到部署機(jī)器上并且通過部署機(jī)器來遠(yuǎn)程部署所有的WAS 服務(wù)器。


      清單 15.部署 WAR
                      
      <stafcmd>
      <location>'%s' % machine </location>
      <service>'process'</service>
      <request>'start command "/root/script/deploywar.sh" username "root" 
      password "password" workdir "/root/script/work" wait 
      stdout /root/script/deploy.log STDERRTOSTDOUT'
      </request>
      </stafcmd>
      

      我們選擇通過一臺部署機(jī)器來部署 WAR 的原因是這樣做維護(hù)比較簡單,如果 WAS 服務(wù)器IP 改變或者增加時,只需要更改部署服務(wù)器的部署腳本即可,甚至對 STAX 腳本也不用更改。當(dāng)然也可以選擇每臺 WAS 分別對自己部署 WAR,這樣當(dāng) WAS 服務(wù)器增加時,需要對 STAX 腳本做一點更改,添加相應(yīng)的 WAS 服務(wù)器。

      在編譯機(jī)器上調(diào)用測試代碼

      部署完成后,在編譯機(jī)器上調(diào)用測試代碼(包括 RFT 代碼)來測試示例 Web Service 程序。

      調(diào)用代碼有兩種方式:

      1. STAX 直接調(diào)用遠(yuǎn)程機(jī)器上的 Java 命令來執(zhí)行
      2. STAX 調(diào)用遠(yuǎn)程機(jī)器上的 Ant 腳本來執(zhí)行

      為了演示這兩種方式的用法,我們使用 Ant 腳本來調(diào)用 JUnit 測試代碼,使用 Java 命令來調(diào)用 RFT 代碼。但在實際使用過程中,我們推薦使用 Ant 腳本來調(diào)用。


      清單 16. 調(diào)用測試代碼
                      
      <stafcmd>
      <location>'%s' % machine </location>
      <service>'process'</service>
      <request>'start command "c:/apache-ant-1.6.5/bin/ant.bat -buildfile %s/runTest.xml 
      > %s/runTest.log"  username "Administrator" password "password" workdir %s wait' 
      % (sourceLocation, sourceLocation, sourceLocation)
      </request>
      </stafcmd>
      <stafcmd>
      <location>'%s' % machine </location>
      <service>'process'</service>
      <request>'start command "java -cp "%s\bin\rational_ft.jar" -Drational_ft.install.dir
      ="%s\bin" com.rational.test.ft.rational_ft -datastore "%s" -rt.log_format "html" 
      -rt.bring_up_logviewer false -playback testscript.VerifyWebService 
      >%s/runRFTTest.log"  username "Administrator" password "password" workdir %s wait' 
      % (RFTLocation, RFTLocation, sourceLocation, sourceLocation, sourceLocation)
      </request>
      </stafcmd>
      

      第一個 STAFCMD 使用 Ant 來調(diào)用 Junit 測試代碼,可以看出命令比較簡單。而第二個STAFCMD 使用 Java 來調(diào)用 RFT 測試腳本,命令要復(fù)雜得多,這樣會給維護(hù)帶來一定的困難,因此推薦使用 Ant 來編譯和調(diào)用。

      收集產(chǎn)生的日志文件

      在部署和測試完成后,控制機(jī)器需要遍歷每個 WAS 服務(wù)器(包括編譯機(jī)和部署機(jī))來收集日志文件,也就是復(fù)制文件到控制機(jī)器上。這與清單 7 類似。

      至此,我們已經(jīng)完成了這個 STAX 腳本的編寫。需要指出的是,所有的 STAX 腳本只需要在控制機(jī)器上執(zhí)行即可,部署機(jī)、編譯機(jī)以及測試機(jī)器完成不知道這些代碼的存在,它們只需要安裝 STAF 并且信任控制機(jī)器即可。

      配置 CruiseControl

      安裝 CruiseControl

      CruiseControl 是一個非常容易使用的持續(xù)集成工具。讀者可以從它的官方網(wǎng)站下載最新版的CruiseControl 2.7 安裝包進(jìn)行安裝。由于安裝十分簡單,本文略過其安裝過程。

      驗證 CVS 配置

      在 Dos 命令行窗口中運(yùn)行如下命令來驗證你可以從 CVS 檢出源代碼 (假定我們使用 cygwin來連接 CVS )

      cd <build_home> 
      set CVS_RSH=c:\cygwin\bin\ssh.exe 
      \progra~1\cvs\cvs -d :ext:user@cvshostname:/cvsroot/sampleproject/ checkout -d <build_home> Build 
      

      配置完成 CVS 后,在 build.xml 中添加如下任務(wù):


      清單17. 檢出 CVS 上測試源代碼的 ant 腳本
                      
      <target name="getSrc">
             <echo message="Extracing source from CVS in to ${build.src.dir}" />
             <cvs
                  cvsRoot=":ext:user@cvshostname:/cvsroot/sampleproject/"
                  command="checkout -P"
      	    cvsRsh="c:\cygwin\bin\ssh.exe"
      	    package="src/test"
      	    dest="${cvs.dir}"/>
             <copy todir="${src.dir}">
      	  <fileset dir="${cvs.dir}/src/test>
                   <exclude name="**/CVS/**"/>
      	  </fileset>
             </copy>
         </target>
      

      注意:用戶也可以直接通過配置使用 CruiseControl 來檢出和編譯源代碼。但是由于在本文的場景中,編譯這些測試代碼需要有特定的類庫支持,而 CruiseControl 所處的控制機(jī)沒有安裝這些類庫。因此在本文中我們使用一個 ant 腳本來將代碼從 CVS 檢出并在后面的步驟中將其發(fā)布到編譯機(jī)上進(jìn)行編譯。

      在 CruiseControl 中配置定時器

      為了讓測試腳本能夠每天定時運(yùn)行,需要在 CruiseControl 中配置定時器。在 CruiseControl 的安裝目錄中找到 “config.xml” 并添加下面的配置代碼:


      清單 18. 在 CruiseControl 中配置定時器
                      
      <schedule interval="300">
        <composite time="0030">
      <ant anthome="C:\Program Files\CruiseControl\apache-ant-1.6.5" target="buildAll"
      			buildfile="d:\ build\build.xml"/>
      <exec command="d:\STAFDirectory\script\execute.bat" />
      </composite>
       </schedule>
      

      上述的設(shè)置設(shè)定了 1 個定時器,在凌晨 3 點執(zhí)行。定時器先運(yùn)行一個 Ant 腳本將代碼檢出復(fù)制到一個本地文件夾中,再運(yùn)行一個批處理命令 “execute.bat” 來啟動后續(xù)的 STAF 命令。

      啟動 STAX 腳本

      當(dāng)測試腳本源代碼被檢出到一個本地文件夾后,批處理命令 “execute.bat” 被執(zhí)行。這個批處理命令只有一行代碼,就是執(zhí)行一個 STAX 任務(wù):

      staf local stax execute file D:\\STAFDirectory\\script\\main.xml wait
      

      這個 STAX 任務(wù)已經(jīng)在前面的章節(jié)中做了詳細(xì)的介紹,此處不再重復(fù)。

      合并 JUnit 測試日志

      在本場景中,當(dāng)測試運(yùn)行完成后測試的結(jié)果和日志需要被發(fā)布到 CruiseControl 的 Web 控制臺中。但是由于測試執(zhí)行是在另一臺服務(wù)器上完成的,因此 CruiseControl 所在的控制機(jī)不能直接訪問這些日志。我們只有創(chuàng)建另一個 STAX 任務(wù)把測試日志從執(zhí)行測試的編譯機(jī)上復(fù)制到控制機(jī)上。

      CruiseControl 內(nèi)建了對 JUnit 產(chǎn)生的 XML 格式的日志的支持。為了讓 CruiseControl 能夠正確的顯示測試日志,需要在其配置文件 “config.xml” 中添加如下設(shè)置:


      清單19. 在 CruiseControl 中合并 JUnit 測試日志
                      
      <log>
      <merge dir="projects/${project.name}/target/test-results" />
      </log>        
      

      發(fā)布 RFT 日志和編譯的運(yùn)行時代碼到 CruiseControl 控制臺

      RFT 運(yùn)行的日志文件有兩種類型,純文本日志和 HTML 格式的日志。CruiseControl 目前還不支持直接顯示 RFT 日志文件。因此我們只能把 RFT 產(chǎn)出的 HTML 日志文件作為一種編譯產(chǎn)出放置在特定文件夾下。這樣用戶可以通過 CruiseControl 控制臺直接訪問該 HTML。

      在編譯機(jī)上編譯得到的 WebService 和客戶端的 war 文件作為一個編譯產(chǎn)出也被存檔保留,并通過 CruiseControl 發(fā)布。當(dāng)測試發(fā)現(xiàn)缺陷后,測試員可以通過這些 war 文件來追溯到某一特定版本的編譯產(chǎn)出并重現(xiàn)缺陷,開發(fā)人員則可以在這一基礎(chǔ)上進(jìn)行調(diào)試和修正。

      添加如下代碼到 CruiseControl 配置文件 “config.xml” 中:


      清單20. 在 CruiseControl 中發(fā)布 RFT 測試日志
                      
      <publishers>
      <onsuccess>
      	<artifactspublisher dest="artifacts/${project.name}" 
      	    dir="projects/${project.name}/target/buildArtifacts" />
      </onsuccess>
      </publishers>
      

      JUnit Test Case 示例

      本章介紹用于測試 Web Service 的 JUnit Test Case 示例,這個例子將詳細(xì)說明如何利用HttpUnit 來測試 Web Service。在這個例子中,共有三方參與,分別為 Web Service Provider、Web Service Client 和 Test Client。首先由 Test Client 向 Web Service Client 發(fā)出 HTTP 測試請求,Web Service Client 在驗證用戶身份后,生成相應(yīng)的 SOAP 請求發(fā)給 Web Service Provider,

      Web Service Provider 同樣在驗證用戶身份后為其提供 Web Service 服務(wù),并將結(jié)果仍以 SOAP的形式返回到 Web Service Client,再由 Web Service Client 以 HTTP 形式返回結(jié)果給 Test Client。最后由 Test Client 對返回結(jié)果的正確性進(jìn)行判斷并給出測試結(jié)果。JUnit Test Case 示例如清單 21 所示。

      清單 21. JUnit Test Case 示例

      01 public class SampleTest extends TestCase {

      02 private String invoke_client(

      03 String requestString, String clientURL, String providerURL) {

      04 String result = null;

      05 String requestURL = clientURL + "?endpoint=" + providerURL

      06 + "&requestString=" + requestString;

      07 WebConversation wc = new WebConversation();

      08 wc.setAuthorization(SampleConst.Username, SampleConst.Password);

      09 WebRequest req = new GetMethodWebRequest(requestURL);

      10 WebResponse resp;

      11 String responseString;

      12 try {

      13 resp = wc.getResponse(req);

      14 responseString = resp.getText();

      15 } catch (AuthorizationRequiredException e) {

      16 result = "Invalid UserID or Password.";

      17 return result;

      18 } catch (Exception e) {

      19 result = "Exception on HTTP request";

      20 return result;

      21 }

      22 int checkNames = responseString.indexOf("User names strings match");

      23 int checkRequest = responseString.indexOf("Request strings match");

      24 if ((checkStrings == -1) | (checkNames == -1) | (checkRequest == -1)) {

      25 result = "Strings not match";

      26 }

      27 return result;

      28 }

      29 public void test_sample_case_1() {

      30 String requestString = "sample_case_1";

      31 String result = invoke_client(requestString,

      32 SampleConst.ClientWebURL,SampleConst.ProviderWebURL);

      33 assertTrue(result, result == null);

      34 }

      35 }

      清單 21 展示了訪問 Web Service 的 JUnit Test Case 示例。

      其中,第 2-29 行定義了 invoke_client 函數(shù),通過 WebConversation 對 Web Service 進(jìn)行訪問。第 5-6 行設(shè)置了 Web Service Client 的地址,endpoint 為 Web Service Provider 的地址。第 8 行為訪問 Web Service 添加了身份認(rèn)證信息。第 12-21 行訪問 Web Service,將結(jié)果存入 responseString。如果在訪問過程中發(fā)生異常,則直接返回錯誤信息。第 22-28 行對返回結(jié)果進(jìn)行驗證,如果發(fā)現(xiàn)結(jié)果錯誤,則返回錯誤信息。否則返回 null 表示訪問成功。

      第 30-35 行為一個 Test 的例子,通過調(diào)用 invoke_client 對 Web Service 進(jìn)行測試,并驗證返回的錯誤消息是否為 null。如果為 null 表示測試成功,反之則失敗。

      結(jié)論

      本文使用 CruiseControl、STAF(STAX)、JUnit、Rational Functional Tester 通過一個簡化的具體場景展示了自動化測試平臺的實現(xiàn)。這個平臺不僅可以大大簡化測試人員的工作量,減輕測試人員的工作負(fù)擔(dān),也能保證開發(fā)版本的穩(wěn)定性,使開發(fā)人員盡早知道新版本的問題,增強(qiáng)開發(fā)人員的信心。

      本文僅代表作者本人觀點,不代表 IBM 公司觀點。


      參考資料

      作者簡介

      崔俊濤是 IBM 上海全球?qū)嶒炇业能浖こ處煛T赟AL_FIT部門工作,現(xiàn)正致力于自動化測試的開發(fā)和研究。他感興趣的技術(shù)有 SOA, EAI。你可以通過郵件 cuijunt@cn.ibm.com 與他聯(lián)系。

      費伽,IBM 軟件開發(fā)實驗室的軟件工程師。他在多個 J2EE 平臺項目中參與開發(fā)與項目管理,對 Web 應(yīng)用開發(fā),SOA 軟件架構(gòu),測試自動化有濃厚的興趣。你可以通過郵件 feijia@cn.ibm.com 與他聯(lián)系。

      陳頡,上海交通大學(xué)的研究生,現(xiàn)在 IBM 上海全球?qū)嶒炇?SAL&FIT 部門實習(xí),致力于自動化測試的開發(fā)。你可以通過郵件 chenjieee@hotmail.com 與他聯(lián)系。

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多