6.2 分析JsUnit
2001年初,Edward Hieatt開始“移植”JUnit,目的是在瀏覽器中測試JavaScript。從那以後,JsUnit的下載次數已近10 000次,大約300人加入了JsUnit的新聞群組。JsUnit支援一般的xUnit功能,完全用JavaScript編寫,如果你習慣使用JUnit或者類似的xUnit架構,就會發現JsUnit使用起來相當簡單直觀。
JsUnit也有一些不同的地方:這裡也有setUp()和tearDown(),不過現在作為函數,而不是方法;測試函數(而不是測試方法)分成多個測試頁(而不是測試案例);另外JsUnit提供了自己的基於HTML的測試回合工具。表6-1對這兩個架構做了比較。
表6-1 JUnit與JsUnit的比較
JUnit |
JsUnit |
Test類擴充 TestCase |
測試頁包含jsUnitCore.js |
測試方法 |
測試函數 |
Test類 |
基於HTML的測試頁 |
TestSuites |
基於HTML的測試集 |
多個測試回合工具 |
基於HTML/JavaScript的測試回合工具 |
setUp()和tearDown()方法 |
setUp()和tearDown()函數 |
在虛擬機器中運行 |
在瀏覽器中運行 |
用Java編寫 |
用JavaScript編寫 |
6.2.1 起步
對於JsUnit,起步很簡單,只需從JsUnit網站(www.edwardh.com/jsunit/)下載JsUnit zip檔案。把這個壓縮檔解開,會得到一個jsunit檔案夾,可以把Web伺服器放在這裡,這樣整個團隊或者整個組織就能更容易地使用JsUnit。JsUnit的大部分“核心”都在jsunit/app目錄中,在這裡可以看到jsUnitCore.js、jsUnitTracer.js和jsUnitTestManager.js,另外還有其他一些檔案。如果你想運行具體的JsUnit測試,可以使用testRunner.html來運行jsunit/tests目錄中找到的任何測試頁。如果你在使用IntelliJ,而且想具體使用JsUnit,jsunit/intellij目錄中包含了需要的所有適當檔案。
6.2.2 編寫測試
用JsUnit編寫測試與用JUnit編寫測試很相似。測試函數不能有任何參數,必須有一個首碼test,例如testDateValidation()。測試函數包含在一個測試頁(test page)中,這類似於JUnit中的一個Test類。測試頁必須包含jsUnitCore.js檔案,解開JsUnit zip檔案後,就會在jsunit/app目錄中找到這個檔案。包含這個JavaScript檔案實際上就是把一個外部JavaScript檔案增加到頁面中;只需使用指令碼元素<script language="JavaScript" src="jsUnitCore.js"></script>來引用這個檔案,要記住,如果你的目前的目錄不是jsunit/app目錄,則還需要提供jsUnitCore.js檔案的相關路徑資訊。當然,在測試頁中可以包含任意多個其他函數或JavaScript;實際上,把多個JavaScript函數放在分開的檔案中,是一個很好的做法。測試函數也可以放在單獨的JavaScript檔案中;不過,如果這樣做,就需要使用exposeTestFunctionNames()方法,這樣JsUnit才能找到測試函數。實際上,如果需要針對不同的頁面內容建立測試,可以把測試函數放在一個單獨的檔案中,這樣能避免複製-粘貼問題帶來的痛苦。
一般地,JsUnit會自動探索測試函數,就像JUnit會發現所有測試方法一樣。不過,有些作業系統/瀏覽器不能合作。如果你發現不能如你所願地發現測試函數,使用exposeTestFunctionNames()方法就能解決這個問題。
斷言方法
現在你對測試函數和測試頁有一定的瞭解了,下面需要寫一些實際的測試!與用JUnit一樣,你可以使用斷言方法(assert method)。斷言方法是任何單元測試的基本模組,它們只是一些簡單的布林運算式,可以指示一個給定語句為true還是false。宣告失敗時,就會產生一個錯誤,這樣將得到眾所周知的紅條。與JUnit不同,JsUnit沒有提供那麼豐富的斷言方法,但是已經足夠你測試JavaScript代碼了。注意,除了fail()方法的注釋外,其他斷言方法的注釋都是可選的(這與JUnit類似,甚至也“不正確”地把選擇性參數放在最前面,而不是最後)。
assert([comment], booleanValue)
assertTrue([comment], booleanValue)
assertFalse([comment], booleanValue)
assertEquals([comment], value1, value2)
assertNotEquals([comment], value1, value2)
assertNull([comment], value)
assertNotNull([comment], value)
assertUndefined([comment], value)
assertNotUndefined([comment], value)
assertNaN([comment], value)
assertNotNaN([comment], value)
fail(comment)