讓編譯和測試過程自動化

Ant 和 JUnit 讓您與 XP 夢想更近一步

Erik Hatcher ([email protected])
eBlox 高級設計師
2001 年 8 月

逐步遞增測試和持續編譯是極端編程方法基礎的兩種。 把兩者合併成爲一個單獨的、自動進行的過程 — 加上自動生成電子郵件報告 — 您就將在向 XP 夢想前進的道路上邁出堅實的步子。請跟隨 Erik Hatcher,他向您展示了他是如何修改流行的 Ant 1.3 和 JUnit 測試框架,以達到讓編譯和測試過程完全的、用戶化的自動化。

極端編程(XP)主要原則的其中之一是程序員必須執行定期的單元測試,還必須不斷的將變化集成到類似產品的環境中去。此外,XP 建議儘可能讓這個過程自動化。畢竟,如果開發者像生產代碼一樣熱切的創建測試案例,過程會相對的輕鬆些。

如果單元測試做的好的話,您應該會對每一段代碼(特別是由個別類標明的)都能正常運行而滿意。執行持續的或者不穩定的編譯讓您明白當代碼集成到生產環境時它是如何生效的。在開發週期中集成單元測試和定期自動的編譯,向您和您的客戶保證了代碼發佈時是可靠的。

在本文中,我將爲自動的編譯和測試過程採取實用的方法。使用 Ant 1.3 和 JUnit 測試框架,將像您展示如何自動化一個過程,這個過程捕獲每個測試套件運行的相關信息、生成有吸引力的報告並用電子郵件發送這個報告。雖然這些性能有許多隱含在 Ant 中,但我還是修改了許多核心任務來更好地滿足要求。這些修改是本文的中心,它們將全部結合到 Ant 的下一個發行版中。可以在本文附帶的源文件中找到所有補丁(請參閱參考文件)。您可能需要在閱讀時回顧一下代碼。此外,如果不熟悉 Ant 1.3,可能需要在繼續這篇文章時學習官方的 Ant 文檔(請參閱參考資料)。

爲什麼使用 Ant 和 JUnit?
Ant 1.3 是編譯工具中的實際標準。由於用 Java 語言編寫,Ant 是開放源代碼的,可以在多種平臺上運行,併爲編譯過程帶來了很大的靈活性。JUnit 測試框架也是開放源代碼的,它被廣泛使用,並與 Ant 的編譯過程集成(想學更多關於 Ant 和 JUnit 的知識,請參閱參考資料)。

Ant 1.3 加上可選的 <junit> 以及 <junitreport> 任務,不經修改就可以啓動基本編譯和測試的自動過程。這一過程如下:

  • 運行 JUnit 測試實用程序
  • 捕獲測試結果
  • 創建吸引人的 HTML 總結報告

一旦捕獲結果,就可以使用 XML 格式化器將每個測試套件運行的故障和錯誤數,連同軟件包和類名還有測試套件的執行時間一起引入。對於每個測試套件,都有以下信息被捕獲:

  • 測試案例的名稱
  • 執行的持續時間
  • 故障或錯誤的類型(如果適用)
  • 任何故障或錯誤的詳細信息

這個構想中少了些什麼
雖然功能上很完美,但上面描述的自動化既不理想也不完整。通過修改 JUnit 任務中的幾個,我們可以創建按如下步驟運行的自動過程。

  • 執行 JUnit 測試
  • 將結果記錄到 XML 文件或其它格式的文件
  • 將結果轉化爲基於 XSL 格式的測試報告
  • 將這個報告轉化爲 HTML 格式
  • 用電子郵件發送報告

請給我更多數據
除了將 Ant 和 JUnit 擴展到能自動進行編譯和測試的過程的程度外,我還添加了測試期間捕獲的標準數據。即,我需要知道使用的是什麼操作系統、測試的日期/時間、支持測試運行的 JVM 版本以及 classpath。

爲捕獲這個信息,我對 Ant 的 JUnit 相關類中的四個類:JUnitTaskJUnitTestJUnitTestRunner 以及 XMLJUnitResultFormatter 做了簡單修改。您會在附帶的源文件中發現這些變化。

作爲附帶的優點,當擴展捕獲的數據時,最終捕獲的不僅是在測試套件運行時特定狀態的信息,而且還包括了整個 Ant 的操作屬性集。其中包含系統屬性和內部 Ant 屬性(例如用戶定義的屬性)。

讓數據報告自動化
對 Ant 的 <junit> 任務進行擴展,使之能提供額外狀態的信息之後,下一步就是啓用自動化的數據報告。

使用 Ant 的最大優勢之一是它的可擴展性。 對於使用帶有 XML 格式化器(<formatter type="xml"/>)的 <junit> 任務運行的每個測試類,都創建了一個 XML 文件。<junitreport> 任務提供了一種很好的將所有收集的數據聚集到一起的方法。使用 XSLT,它會將測試數據轉化爲一種可以被輕鬆理解的 HTML 格式報告。

<junitreport> 可被輕鬆擴展,允許用戶自定義的 XSLT 文件用作報告生成。XSLT 文件內建於 Ant 的 optional.jar 文件中。我將它和它必備的伴侶 toolkit.xsl 一起解壓縮到本地目錄,然後修改 overview_summary.xsl 文件以便將 Ant 屬性引入報告。 而在 build.xml 中,我指定了“noframes”報告。在“測試套件”的相應部分中,添加到 overview_summary.xsl 中的代碼斷如清單 1 所示。

清單 1. overview_summary.xsl 代碼段用以顯示新添入的屬性

<table>
     <xsl:for-each select="./Properties/Property">
         <xsl:sort select="@name"/>
         <tr>
             <td><xsl:value-of select="@name"/></td>
             <td><xsl:value-of select="@value"/></td>
         </tr>
     </xsl:for-each>
</table>

一旦修改了這些文件,您就可以運行編譯。負責運行 JUnit 測試和創建 HTML 報告的 build.xml 代碼段如清單 2 所示。

清單 2. build.xml 中用以運行 JUnit 測試和創建 HTMl 報告的部分


<target name="junit" depends="compiletests"
          description="Execute Unit Tests">
    <junit>
      <formatter type="xml" />
      <batchtest>
        <fileset dir="${build}">
          <include name="test/**/*Test.class" />
        </fileset>
      </batchtest>
    </junit>

    <junitreport>
      <fileset dir=".">
        <include name="TEST-*.xml"/>
      </fileset>
      <report format="noframes" styledir="etc/xsl"/>
    </junitreport>
</target>

關於這個編譯代碼段,您應該注意的主要事情是 <junitreport> 中 <report> 元素的 styledir 屬性;它指定了用戶自定義的 XSLT 文件所在的目錄。爲捕獲日期/時間戳,您需要在 build.xml 某處的 <junit> 任務前引入 <tstamp> 任務。

讓電子郵件任務自動化
Ant 有一個內建的 <mail> 任務,但不幸的是這個任務只有文本消息的性能,不能處理文件附件。 但最近,一項任務被提交到 Ant 開發組,它實現了 MIME 郵件的性能。

我和另兩個積極的 Ant 開發者一起工作,改善這個最近提交的任務,這樣它就可以支持 Ant 的 FileSet 特性以及抄送和暗送的郵件功能。我還添加了另一個很好的特性 — 將文件附加到電子郵件消息正文的能力。

現代的電子郵件閱讀器可以像 MIME 那樣顯示附帶的 HTML 內容,還可以像瀏覽器那樣解讀 HTML 代碼。圖 1 顯示了使用 <mimemail> 任務、用 Ant 發送的 JUnit 報告電子郵件樣本是什麼樣子。

圖 1. 用 Ant 發送的 JUnit 報告樣本
Figure 1. Sample JUnit report sent from Ant

發送電子郵件的代碼如清單 3 所示。

清單 3. build.xml 中用來發送電子郵件的代碼段


<target name="mail">
    <taskdef name="mimemail" 
classname="org.apache.tools.ant.taskdefs.optional.mail.MimeMail"/>
      <tstamp/>
      <mimemail messageMimeType="text/html"
                   messageFile="overview-summary.html"
                   tolist="[email protected]"
                   mailhost="mail.eblox.com"
                   subject="JUnit Test Results: ${TODAY}"
                   from="[email protected]">
        <fileset dir=".">
          <include name="TESTS-*.xml"/>
        </fileset>
      </mimemail>
</target>

代碼註釋:

  • <taskdef> 用來定義 <mimemail> 任務,因爲現在 Ant 沒有提供這個功能。以後,這個任務可能會成爲 Ant 的可選任務之一;那麼 <taskdef> 就會成爲多餘。

  • <tstamp> 用來創建用在電子郵件主題中的 TODAY 屬性。在 build.xml 的“準備”或“初始化”階段包含 <tstamp> 任務很常見,所以根據您的情況,它可能是多餘的。

  • <mimemail> 具有清楚的自解釋的語法。提供的代碼中包含了這項任務的 Ant 風格的幫助文件(請參閱參考資料)。不僅 HTML 報告被髮送(使用 messageFile 屬性以便附加到消息的正文部分),而且原始的 XML 結果文件也作爲標準 MIME 附件用 <fileset> 被髮送了。

  • <junitreport> 在前面創建了一個名叫 overview-summary.html 的文件(因爲指定了“noframes” 選項)。

排障、測試和部署
我爲 Ant 開發團體提供了剛纔討論的所有的代碼修正,他們已經認可將其包含到以後的發行版中去。但是,因爲官方的 Ant 發行版還沒有包含這篇文章中使用的技巧,在讓這些技巧爲您服務之前還需要採取一些措施。

讓代碼生效
第一,這些代碼的修正是基於 Ant 1.3 發行版的;這是我將推薦的用於這代碼的唯一 Ant 版本。 提供的代碼包含了 JUnitMail.jar 和用於生成 jar 文件的源代碼。這個 jar 文件必須存在於啓動 Ant 環境中的 classpath 裏 — 在 Ant 的 optional.jar 之前

如果您是個典型的 Ant 用戶,您通過 $ANT_HOME/bin 中的包裝腳本之一運行 Ant。這些包裝腳本在啓動 Ant 前將所有 $ANT_HOME/lib 中的 jar 文件放入 classpath。在 Windows 平臺下只要將 JUnitMail.jar 放入 $ANT_HOME/lib 目錄,用 ant.bat 就可以處理 classpath 問題。

如果遇到過古怪的行爲(例如,也許從 <junit> 捕獲的額外參數沒有在 XML 文件中出現),那麼就調試在包裝腳本中用到的 classpath(例如,ant.bat 中的 %LOCALCLASSPATH% )並修改包裝腳本,確保 classpath 中 JUnitMail.jar 在 optional.jar 之前。

測試代碼
在將這新的代碼集成到 classpath 中以後,用 XML 格式化器測試一個簡單的 JUnit 測試示例(如清單 2 所示)確保捕獲了額外的 Ant 屬性。

額外屬性作爲 <Property> 元素在 XML 格式化器中被捕獲。如果,由於某種原因致使屬性元素沒有出現,就可能是一個 classpath 的問題。

確保修正後的 JUnit 任務正在被使用,一個保險的辦法是使用我的 JUnitMail.jar 版本中提供的 JUnitTask.classJUnitTest.classJUnitTestRunner.classXMLJUnitResultFormatter.class 來代替 optional.jar 中相應的文件。

<mimemail> 任務有兩個依賴條件 — JavaMail 和 Java 活動框架(請參閱參考資料)。在啓動 Ant 時,這兩個 jar 文件必須放在 classpath 中,以便使用 <mimemail>。

定製佈局
您可以通過調整 XSLT 文件定製 JUnit 結果的 HTML 佈局。我通過爲每個測試套件在隱藏的 <DIV> 中添加額外屬性以及添加一些用於隱藏及顯示該額外信息的 JavaScript 的方法修改了 Ant 的標準佈局。這些 JavaScript 技巧可以在 Internet Explorer 中生效,但在 Netscape 中不起作用(它顯示了所有的屬性,沒有隱藏)。

我添加新捕獲屬性的首要目的僅僅是讓那些信息可用,不過將這些屬性結合到 HTML 報告中的方法,還有很大的改進餘地。(請記住,如果您做了任何改進,請將之提交到 Ant 開發者和用戶團體,讓我們大家分享!)

讓 XP 成真
一旦您使用了我的補丁,讓編譯和測試過程自動進行只是個在 cron 作業(或者是 Windows 平臺上的 at 作業)中包裝 Ant 執行的問題。

理想化的想法是,自動進行的過程將會把代碼從您的源代碼管理系統中提取出來,完成編譯、執行單元測試、然後每晚用電子郵件發送結果。還有將整個編譯日誌捕獲並用電子郵件發送或張貼到 intranet 站點,這樣您就與“持續集成”和 XP 夢想接近了一步。

參考資料

  • 請參與有關本文的討論論壇

  • 您會在這個壓縮文件中找到所有 Ant 的 JUnit 任務和新的 MimeMail 任務的補丁, 以及增強的 XSL 文件。

  • 請從 Jakarta project 下載 Ant 1.3

  • 如果直到今天您仍沒有(使用 JUnit)測試代碼,現在機會來了。

  • 若要開始合併 Ant/JUnit(包括如何創建 JUnit 測試案例),請閱讀 Malcolm Davis 的“Incremental development with Ant and JUnit”(developerWorks,2000 年 11 月)。

  • 出色的文章,“Ant in Anger,”描述了 Ant 在典型的產品開發環境下的使用。

  • 請嘗試極端編程站點以獲取更多這個主題的信息。

  • JavaMailJava 活動框架是 <mimemail> 任務必需的。

  • Ant 和 JUnit 是對 WebSphere 應用開發環境的完美的測試讚美辭;版本 4.0 提供了增強的擴展,例如 Java 業務規則,使得不必重寫代碼就可以改變 Java 應用。

  • 需要企業級的系統測試的幫助,請看 IBM Performance Management, Testing and Scalability Services 提供了些什麼(包含一個有關企業測試的庫,PDF 格式)。

  • 請在 developerWorks Java 技術專區查找更多 Java 參考資料。

 

關於作者
Erik Hatcher 今年曾瘋狂沉迷於 dot-com,但他發現他的歸宿在 eBlox,在那裏用 XP 方法開發 J2EE 解決方案。請通過 [email protected] 與他聯繫。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章