程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Jacks:Java的兼容性測試 開放源碼之路

Jacks:Java的兼容性測試 開放源碼之路

編輯:關於JAVA

什麼是 Jacks?

Jacks 測試套件檢查 Java 編譯器是否符合 JLS(Java 語言規范)。它由大量小測試案例組成,每個測試都側重於 JLS 中特定的部分。Eric Blake 為 Jacks 項目作出了很大貢獻,他從面向細節領域描述了這種類型測試的好處。“通過生成帶有指定編譯行為的小測試案例,然後將每個案例的執行自動化,編譯器作者或調試者可以快速找出 Java 源碼到字節碼轉換中存在的問題。”

開發 Jacks 背後的概念是要簡化對多編譯器或多編譯器配置所運行的測試(例如,對上兩個發行版的 Jikes 和 Javac 的 JDK 1.3 發行版所進行的一組測試)。如果手工進行,您必須重復地設置環境變量,然後根據所期望的結果來檢查測試結果。而通過使用 Jacks,只需要更改到存放測試的目錄, 調用 Jacks 框架,然後表明應該使用哪個編譯器配置。

Sun 沒有履行對 Java 開發者所做的承諾激發了 Jikes 小組對 Jacks 項目的設置和運行。Sun 再三聲明它會把 Java、JCK(Java Compatibility Kit)和相關 Java 技術交到一個標准主體的手中。但因為這還沒有實現,從事 Java 項目的開發者就不能使用 JCK 來對日常的開發進行回歸測試。當面對由於不合理的許可證限制而導致的代碼人為不足時,他們傾向於用新的更完善的系統來替換舊系統。這就是發生在 Jacks 上的故事。(盡管 Jacks 由 developerWorks 主持,它受 GPL 而非 IBM Public License 約束。)

使用 Jacks

Jacks 是以 Tcl 編寫的,因此需要確保擁有 Tcl 8.3。(需要版本 8.3 來確保具有 tcltest 擴展和 Unicode 支持,這兩者都是 Jacks 所必需的)。可以下載用於 Windows 的安裝程序和用於 Red Hat x86 的 RPM,也可以更方便地從源代碼中構建。如果您不知道到什麼地方下載,請參閱本文稍後的 參考資料 部分;如果使用的是 Red Hat 7,很可能已安裝了 Tcl 8.3。

安裝了 Tcl 後,需要從 CVS 取出 Jacks。然後通過將編譯器路徑名包括在要測試的編譯器的 Jacks _setup 配置文件中來配置 Jacks。對於每個希望支持的配置都需要一個 _setup 文件。例如,Jacks 帶有 javac_setup 文件。需要編輯該文件來為 javac 設置路徑。Eric Blake 說,“最困難的部分是斷定如何測試 Jikes,因為我在環境中已設置了 JIKESPATH。但我想出了要在 jikes_setup 配置文件中更改什麼內容,一切都很順利。”

從 CVS 模塊中取出 Jacks 源代碼

setenv CVSROOT :pserver:[email protected]:/usr/cvs/jikes

cvs login

paswsd anoncvs

cvs checkout jacks

可以對數量不限的編譯器或編譯器配置使用 Jacks。要除去某一編譯器的配置,只需要刪除其 _setup 文件。

從 CVS 中取出源代碼後,就需要在路徑中包括頂層 Jacks 目錄,這樣才能運行 Jacks shell 腳本。為謹慎起見,最初運行 shell 腳本時應該不帶任何自變量,以確保每項都經過正確配置。

% jacks

如果一切正常,將看到 Jacks 腳本所接受的命令行選項的清單。如果收到錯誤,請檢查在路徑中是否能找到可執行文件 tclsh8.3。Windows 用戶需要直接運行 tclsh83,並將 jacks.tcl 自變量在一般標志之前傳遞給它。還應該考慮安裝 Cygwin UNIX 兼容性層,這樣,象 Unix 用戶一樣,您就可以使用提供的 shell 腳本來運行 Jacks 了。下面的指令假設您使用的是 shell 腳本。

對於測試示例,需要使用 Jikes 編譯器來運行給定子目錄中的所有測試,命令如下:

% cd tests/jls/packages/package-declarations/unnamed-packages

% jacks jikes

開發新的回歸測試

開發新的 Jacks 測試案例非常簡便。照 Eric Blakes 的話說,“基本上,您設計一個簡單的源文件來測試問題,將它放在特定的 Jacks 格式中,然後運行 Jacks。如果編譯器結果與所期望的結果不一樣,它打印出錯誤。”這裡是 Jacks 主頁上教程中有關添加新測試案例的一例:

// File SynchronizedInterface.java

public synchronized interface SynchronizedInterface {}

使用 Jikes 編譯時,生成以下錯誤:

% jikes SynchronizedInterface.java
Found 1 semantic error compiling "SynchronizedInterface.java":
3. public synchronized interface SynchronizedInterface {}
<---------->
*** Error: synchronized is not a valid interface modifier.

如果很快看一下 JLS 的第 9.1.1 節,會發現 synchronized 在該上下文中不是合法的修飾符。如果嘗試使用早期發行版 JDK 中的 Javac 編譯器來編譯相同的類,則不會生成錯誤(該錯誤在稍後的發行版中得到修正)。

% javac SynchronizedInterface.java

現在既然問題得以重現,可以通過以下步驟來對 Jacks 測試套件添加回歸測試案例:

了解應該將測試案例放在哪個目錄中

編寫回歸測試

在 Jacks 框架中運行新測試

tcltest 框架中回歸測試的格式是:

tcltest::test NAME DESCRIPTION {
COMMANDS
} EXPECTED_RESULT

這是 JLS 第 9.1.1 節中的第一個測試,所以 NAME 是 9.1.1-1。

該測試案例在目錄 tests/jls/interfaces/interface-declarations/interface-modifiers (位置基於 JLS 節的名稱)中。

DESCRIPTION 可以是任何想要的內容。

COMMANDS 一節包含了所有 Tcl 命令,但大多數情況只需要 Jacks 中的 saveas 和 compile 方法。

saveas 命令使用兩個自變量:文件名和將保存到文件中的數據。

saveas SynchronizedInterface.java \

{public synchronized interface SynchronizedInterface {}}

compile 命令使用任意數量的命令行自變量,並將它們傳遞給 Java 編譯器。它將返回 PASS、FAIL 或 WARN 來表明編譯器的退出狀態。

EXPECTED_RESULT 是希望從 compile 命令獲得的結果。

在該接口示例中,編譯應該不成功。因此完整的回歸測試應該類似於:

tcltest::test 9.1.1-1 {should generate error on synchronized interface} {
saveas SynchronizedInterface.java \
{synchronized interface SynchronizedInterface {}}
compile SynchronizedInterface.java
} FAIL

檢驗結果

運行測試並檢查結果是完全自動的,因此可以真正地休息一下,看看出現的結果。Jacks 框架在測試目錄中遞歸下降,運行它所找到的所有測試。

如果一切正常,就不打印任何消息。如果測試失敗,將打印有關失敗的描述,如 Mo Dejong 在 清單 1 中顯示的那樣。該例演示了 Javac 中因為第一個構造器調用第二個構造器,第二個又調用第一個所造成的錯誤。JLS 規定這是非法的(第 8.8.5.1 節),因此如果檢測到這種情況,Java 編譯器必須用信號通知該錯誤。

讓我們看看 Jikes 對於同一測試案例是如何做的。在 清單 2 中,我們將使用 Jacks 中的一些特性,可以讓您將模式作為 Jacks 腳本的第三個自變量傳遞。將跳過那些名稱與模式不匹配的測試案例。在這個小案例中,模式就是測試案例的名稱。在該例中,請注意我們所感興趣的那個測試案例是如何通過的,其它測試案例是如何跳過的。上面的輸出表明在 Javac 編譯器中找到的錯誤在 Jikes 中並不存在。

盡管人類可讀的結果非常有用,但在您有許多要處理的測試案例的情況下,它們很快就會變得非常難於管理。Jacks 最近慶祝了一個重要的裡程碑:現在它包含了逾 1,000 個 JLS 獨立測試案例。有了這麼多的測試案例,沒人能夠記住在某一時刻哪些案例通過了,哪些又失敗了。但不用害怕,Jacks 包括了一系列記錄和測試結果分析特性,能夠隨時間跟蹤測試結果。這是一項關鍵特性,因為它為 Java 編譯器開發者提供了一種跟蹤錯誤修正狀態和可能回歸的方法。

如何編寫 Jacks,以及為什麼使用 Tcl

當實現例如 Jacks 這樣的測試套件時,腳本語言是個很自然的選擇,而使用 Tcl 也有以下幾個原因:

Tcl 是開放源碼,因此在今後的一段時間內仍然會繼續存在。

易於安裝,不需要編譯腳本。

易於讀寫,腳本語言遠比 C/C++ 更易於掌握。

易於使用字符串處理和常規規則表達式特性。

高度可移植,在比 Java 多的平台上運行。

過去十年中成功地在幾千個組織中使用過

具有諷刺意味的是,它曾是 Sun 項目 :)

Mo DeJong 說,“Jacks 最了不起的一個特性是自生成文檔。” 在 Jacks 主頁上,您可以找到到達測試案例索引頁面的鏈接,這些頁面列出了所有可用的測試案例。它以幾種有用的方式進行索引和交叉引用。可以方便地通過名稱查找測試案例,也可以通過現有測試來發現某個 JLS 章節的內容是多麼完善。Tcl 高度動態的語言特性使自記錄測試案例的實現更容易。

到目前為止,Jacks 支持以下幾種 Java 編譯器:

JDK 1.3(1.1 和 1.2 也可以使用,但已經過時了)

Jikes,IBM 的開放源碼 Java 編譯器

Kaffe,利用了 Kopi 編譯器

GCJ,到 gcc 的 Java 前端

隨處改進 Java 編譯器

Jacks 最初著重只為 Jikes 項目提供編譯器測試。原來的目標是要替換為 Jikes 創建的自制測試系統,但這個初衷由於太難建立和使用而被放棄了。人們很快發現,如果測試套件變得更常規一些,就可以為其它 Java 編譯器項目使用。這樣將會導致已提交測試案例在數量上的增加。至少,讓其它 Java 專家評估一下正確性測試案例也並無大礙。

Jikes 項目自然大大利用鑒了 Jacks,但 GCJ 和 Kopi 編譯器項目又如何呢?Tom Tromey,Red Hat 的常任 Java 領導者,已經意識到了 Jacks 開發對於 GCJ 項目的作用。“Jacks 對於 GCJ 項目已經有了實際意義。每當我在進行前端編譯器更改時就會運行 Jacks,並定期使用 Jacks 查找 GCJ 中的錯誤。添加測試是樁小事。框架非常易於使用,考慮也很周到。”

在第一次運行了 Jacks 後,Kopi 編譯器的項目經理 Thomas Graf 也成了一個擁戴者。“第一次運行產生了 169 個失敗的測試。在基於對某些失敗測試的分析而應用一些修正後,失敗的測試數為 147 個。這些結果非常振奮人心(對於 Jacks:)。結論是:Jacks 測試套件對於提高編譯器的質量來說確實是一種非常有價值的工具!”

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved