编写junit 测试_编写JUnit测试的另一种方法(Jasmine方法)
編寫junit 測試
最近,我為一個小型個人項目編寫了很多Jasmine測試。 我花了一些時間才終于感到正確地完成了測試。 在此之后,當切換回JUnit測試時,我總是很難過。 由于某種原因,JUnit測試不再那么好,我想知道是否有可能以類似于Jasmine的方式編寫JUnit測試。
Jasmine是一個受RSpec (Ruby BDD測試框架)啟發的流行JavaScript行為驅動開發測試框架。
一個簡單的茉莉花測試如下所示:
第一行中的describe()函數調用使用AudioPlayer tests描述創建了一個新的測試套件。 在測試套件中,我們可以使用it()創建測試(在Jasmine中稱為specs)。 在這里,我們檢查創建新的AudioPlayer的isPlaying()方法是否返回false。
AudioPlayer實例。
用JUnit編寫的相同測試如下所示:
public?class?AudioPlayerTest?{private?AudioPlayer?audioPlayer;@Before?public?void?before()?{audioPlayer?=?new?AudioPlayer();}@Testvoid?notPlayingAfterInitialization()?{assertFalse(audioPlayer.isPlaying());}... }我個人認為Jasmine測試與JUnit版本相比更具可讀性。 在Jasmine中,對測試沒有任何影響的唯一噪音是花括號和function關鍵字。 其他所有內容都包含一些有用的信息。
在閱讀JUnit測試時,我們可以忽略諸如void,訪問修飾符(私有,公共,..),注釋和不相關的方法名稱(如以@Before注釋的方法名稱)之類的關鍵字。 除此之外,以駝峰案例方法名稱編碼的測試描述不太好讀。
除了提高可讀性外,我真的很喜歡Jasmine嵌套測試套件的功能。
讓我們來看一個更長的示例:
describe('AudioPlayers?tests',?function()?{var?player;beforeEach(function()?{player?=?new?AudioPlayer();});describe('when?a?track?is?played',?function()?{var?track;beforeEach(function()?{track?=?new?Track('foo/bar.mp3')player.play(track);});it('is playing?a?track',?function()?{expect(player.isPlaying()).toBeTruthy();});it('returns?the?track?that?is?currently?played',?function()?{expect(player.getCurrentTrack()).toEqual(track);});});... });在這里,我們創建了一個子測試套件,負責測試AudioPlayer播放曲目時的行為。 內部的beforeEach()調用用于為子測試套件內的所有測試設置通用的前提條件。
相反,在JUnit中為多個(但不是全部)測試共享通用的前提條件有時會變得很麻煩。 當然,在測試中復制設置代碼是不好的,因此我們為此創建了額外的方法。 為了在設置和測試方法之間共享數據(例如上面示例中的track變量),我們必須使用成員變量(范圍更大)。
另外,我們應確保將具有類似前提條件的測試分組在一起,以避免需要閱讀整個測試類來查找特定情況下的所有相關測試。 或者我們可以將事情分成多個較小的類。 但是,然后我們可能必須在這些類之間共享設置代碼……
如果我們查看Jasmine測試,就會發現該結構是通過調用全局函數(例如describe(),it(),…)并傳遞描述性字符串和匿名函數來定義的。
有了Java 8,我們有了Lambdas,所以我們可以做同樣的事情嗎?
是的,我們可以在Java 8中編寫如下代碼:
public?class?AudioPlayerTest?{private?AudioPlayer?player;public?AudioPlayerTest()?{describe("AudioPlayer?tests",?()?->?{beforeEach(()?->?{player?=?new?AudioPlayer();});it("should?not?play?any?track?after?initialization",?()?->?{expect(player.isPlaying()).toBeFalsy();});});} }如果我們暫時假設describe(),beforeEach(),it()和Expect()是采用適當參數的靜態導入方法,則至少可以編譯。 但是,我們應該如何進行這種測試?
出于興趣,我嘗試將其與JUnit集成在一起,結果發現這實際上非常簡單(我將在以后進行介紹)。 到目前為止,結果是一個名為Oleaster的小型圖書館。
用Oleaster編寫的測試如下所示:
import?static?com.mscharhag.oleaster.runner.StaticRunnerSupport.*; ...@RunWith(OleasterRunner.class) public?class?AudioPlayerTest?{private?AudioPlayer?player;{describe("AudioPlayer?tests",?()?->?{beforeEach(()?->?{player?=?new?AudioPlayer();});it("should?not?play?any?track?after?initialization",?()?->?{assertFalse(player.isPlaying());});});} }與前面的示例相比,只有幾處發生了變化。 在這里,測試類使用JUnit @RunWith注釋進行注釋。 這告訴JUnit在運行此測試類時使用Oleaster。 通過靜態導入StaticRunnerSupport。*,可以直接訪問靜態Oleaster方法,例如describe()或it()。 還要注意,構造函數已由實例初始化程序替換,而Jasmine like matcher被標準JUnit斷言替換。
與原始的Jasmine測試相比,實際上有一件事情并不那么出色。 事實是,在Java中,變量需要有效地最終確定才能在lambda表達式中使用。 這意味著以下代碼段不會編譯:
describe("AudioPlayer?tests",?()?->?{AudioPlayer?player;beforeEach(()?->?{player?=?new?AudioPlayer();});... });在beforeEach()lambda表達式內對玩家的賦值將不會編譯(因為玩家實際上不是最終的)。 在Java中,我們必須在這種情況下使用實例字段(如上例所示)。
萬一您擔心要報告:Oleaster僅負責收集和運行測試用例。 整個報告仍由JUnit完成。 因此,Oleaster應該不會對使用JUnit報告的工具和庫造成任何問題。
例如,以下屏幕截圖顯示了IntelliJ IDEA中Oleaster測試失敗的結果:
如果您想知道Oleaster測試在實踐中的外觀,您可以看看Oleaster的測試(用Oleaster本身編寫)。 您可以在此處找到GitHub測試目錄。
通過評論此帖子或創建GitHub問題,隨時添加任何類型的反饋。
翻譯自: https://www.javacodegeeks.com/2014/07/an-alternative-approach-of-writing-junit-tests-the-jasmine-way.html
編寫junit 測試
總結
以上是生活随笔為你收集整理的编写junit 测试_编写JUnit测试的另一种方法(Jasmine方法)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 印度网友怒了!iPhone 15太贵 还
- 下一篇: JDK 14 – JEP 361从预览中