本文通過理論分析和詳細例子向讀者闡述 JUnit 4.4 所帶來的最新特性,讀者通過本文的學習,可以輕松掌握使用 JUnit 4.4 的新特性。
隨著當前 Java 開發的越發成熟,Agile 和 TDD 的越發流行,自動化測試的呼聲也越來越高。若想將單元測試變得自動化,自然 JUnit 這把利器必不可少,這也是 JUnit 自 1997 年誕生以來在 Java 開發業界一直相當流行的原因。
JUnit 是針對 Java 語言的一個單元測試框架,它被認為是迄今為止所開發的最重要的第三方 Java 庫。 JUnit 的優點是整個測試過程無需人的參與,無需分析和判斷最終測試結果是否正確,而且可以很容易地一次性運行多個測試。 JUnit 的出現促進了測試的盛行,它使得 Java 代碼更健壯,更可靠,Bug 比以前更少。
JUnit 自從問世以來一直在不停的推出新版本,目前最新的版本是 2007 年 7 月發布的 JUnit 4.4,它是繼 JUnit4 以來最大的發行版,提供了很多有用的新特性。本文將假設讀者已經具有 JUnit 4 的使用經驗。
JUnit 4.4 概述
JUnit 設計的目的就是有效地抓住編程人員寫代碼的意圖,然后快速檢查他們的代碼是否與他們的意圖相匹配。 JUnit 發展至今,版本不停的翻新,但是所有版本都一致致力于解決一個問題,那就是如何發現編程人員的代碼意圖,并且如何使得編程人員更加容易地表達他們的代碼意圖。JUnit 4.4 也是為了如何能夠更好的達到這個目的而出現的。
JUnit 4.4 主要提供了以下三個大方面的新特性來更好的抓住編程人員的代碼意圖:
assertThat
新的斷言語法(Assertion syntax)—— assertThat
JUnit 4.4 學習 JMock,引入了 Hamcrest 匹配機制,使得程序員在編寫單元測試的 assert
語句時,可以具有更強的可讀性,而且也更加靈活。
Hamcrest 是一個測試的框架,它提供了一套通用的匹配符
Matcher,靈活使用這些匹配符定義的規則,程序員可以更加精確的表達自己的測試思想,指定所想設定的測試條件。比如,有時候定義的測試數據范圍太精確,往往是若干個固定的確定值,這時會導致測試非常脆弱,因為接下來的測試數據只要稍稍有變化,就可能導致測試失?。ū热?
assertEquals( x, 10 );
只能判斷 x
是否等于 10
,如果
x
不等于
10
,測試失?。?;有時候指定的測試數據范圍又不夠太精確,這時有可能會造成某些本該會導致測試不通過的數據,仍然會通過接下來的測試,這樣就會降低測試的價值。
Hamcrest 的出現,給程序員編寫測試用例提供了一套規則和方法,使用其可以更加精確的表達程序員所期望的測試的行為。(具體 Hamcrest 的使用,請參閱
參考資料)
JUnit 4.4 結合 Hamcrest 提供了一個全新的斷言語法——assertThat
。程序員可以只使用
assertThat
一個斷言語句,結合 Hamcrest 提供的匹配符,就可以表達全部的測試思想。
assertThat
的基本語法如下:
assertThat( [value], [matcher statement] ); |
value
是接下來想要測試的變量值;
matcher statement
是使用 Hamcrest 匹配符來表達的對前面變量所期望的值的聲明,如果
value
值與 matcher statement
所表達的期望值相符,則測試成功,否則測試失敗。
assertThat 的優點
assertEquals
,assertNotSame
,assertFalse
,assertTrue
,assertNotNull
,assertNull
等,現在有了 JUnit 4.4,一條 assertThat
即可以替代所有的 assertion
語句,這樣可以在所有的單元測試中只使用一個斷言方法,使得編寫測試用例變得簡單,代碼風格變得統一,測試代碼也更容易維護。
assertThat
使用了 Hamcrest 的 Matcher
匹配符,用戶可以使用匹配符規定的匹配準則精確的指定一些想設定滿足的條件,具有很強的易讀性,而且使用起來更加靈活。如清單 2 所示: // 想判斷某個字符串 s 是否含有子字符串 "developer" 或 "Works" 中間的一個 // JUnit 4.4 以前的版本:assertTrue(s.indexOf("developer")>-1||s.indexOf("Works")>-1 ); // JUnit 4.4: assertThat(s, anyOf(containsString("developer"), containsString("Works"))); // 匹配符 anyOf 表示任何一個條件滿足則成立,類似于邏輯或 "||", 匹配符 containsString 表示是否含有參數子 // 字符串,文章接下來會對匹配符進行具體介紹 |
assertThat
不再像 assertEquals
那樣,使用比較難懂的“謂賓主”語法模式(如:assertEquals(3,
x);
),相反,assertThat
使用了類似于“主謂賓”的易讀語法模式(如:assertThat(x,is(3));
),使得代碼更加直觀、易讀。
// 聯合匹配符not和equalTo表示“不等于” assertThat( something, not( equalTo( "developer" ) ) ); // 聯合匹配符not和containsString表示“不包含子字符串” assertThat( something, not( containsString( "Works" ) ) ); // 聯合匹配符anyOf和containsString表示“包含任何一個子字符串” assertThat(something, anyOf(containsString("developer"), containsString("Works")));
|