詳解Java單元測試之JUnit篇
單元測試是編寫測試代碼,應(yīng)該準(zhǔn)確、快速地保證程序基本模塊的正確性。
JUnit是Java單元測試框架,已經(jīng)在Eclipse中默認(rèn)安裝。
JUnit4
JUnit4通過注解的方式來識別測試方法。目前支持的主要注解有:
- @BeforeClass 全局只會執(zhí)行一次,而且是第一個運(yùn)行
- @Before 在測試方法運(yùn)行之前運(yùn)行
- @Test 測試方法
- @After 在測試方法運(yùn)行之后允許
- @AfterClass 全局只會執(zhí)行一次,而且是最后一個運(yùn)行
- @Ignore 忽略此方法
下面基于Eclipse介紹JUnit的基本應(yīng)用
基本測試
1.新建一個項目叫JUnitTest,我們編寫一個Calculator類,這是一個能夠簡單實(shí)現(xiàn)加減乘除、平方、開方的計算器類,然后對這些功能進(jìn)行單元測試。
public class Calculator { private static int result; // 靜態(tài)變量,用于存儲運(yùn)行結(jié)果 public void add(int n) { result = result + n; } public void substract(int n) { result = result - 1; //Bug: 正確的應(yīng)該是 result =result-n } public void multiply(int n) { } // 此方法尚未寫好 public void divide(int n) { result = result / n; } public void square(int n) { result = n * n; } public void squareRoot(int n) { for (; ;) ; //Bug : 死循環(huán) } public void clear() { // 將結(jié)果清零 result = 0; } public int getResult(){ return result; } }
1.將JUnit4單元測試包引入這個項目:在該項目上點(diǎn)右鍵,點(diǎn)“屬性”,如圖
在彈出的屬性窗口中,首先在左邊選擇“Java Build Path”,然后到右上選擇“Libraries”標(biāo)簽,之后在最右邊點(diǎn)擊“Add Library…”按鈕,如下圖所示
然后在新彈出的對話框中選擇JUnit4并點(diǎn)擊確定,如上圖所示,JUnit4軟件包就被包含進(jìn)我們這個項目了。
2.生成JUnit測試框架:在Eclipse的Package Explorer中用右鍵點(diǎn)擊該類彈出菜單,選擇“New JUnit Test Case”。如下圖所示:
點(diǎn)擊“下一步”后,系統(tǒng)會自動列出你這個類中包含的方法,選擇你要進(jìn)行測試的方法。此例中,我們僅對“加、減、乘、除”四個方法進(jìn)行測試。
之后系統(tǒng)會自動生成一個新類CalculatorTest,里面包含一些空的測試用例。你只需要將這些測試用例稍作修改即可使用。
完整的CalculatorTest代碼如下:
public class CalculatorTest { private static Calculator calculator = new Calculator(); @Before public void setUp() throws Exception { calculator.clear(); } @Test public void testAdd() { calculator.add(3); calculator.add(4); assertEquals(7, calculator.getResult()); } @Test public void testSubstract() { calculator.add(8); calculator.substract(3); assertEquals(5, calculator.getResult()); } @Ignore("Multiply() Not yet implemented") @Test public void testMultiply() { fail("Not yet implemented"); } @Test public void testDivide() { calculator.add(8); calculator.divide(2); assertEquals(4, calculator.getResult()); } }
1.運(yùn)行測試代碼:按照上述代碼修改完畢后,我們在CalculatorTest類上點(diǎn)右鍵,選擇“Run As a JUnit Test”來運(yùn)行我們的測試,如下圖所示
運(yùn)行結(jié)果如下:
進(jìn)度條是紅顏色表示發(fā)現(xiàn)錯誤,具體的測試結(jié)果在進(jìn)度條上面有表示“共進(jìn)行了4個測試,其中1個測試被忽略,一個測試失敗”。
限時測試
對于那些邏輯很復(fù)雜,循環(huán)嵌套比較深的程序,很有可能出現(xiàn)死循環(huán),因此一定要采取一些預(yù)防措施。限時測試是一個很好的解決方案。我們給這些測試函數(shù)設(shè)定一個執(zhí)行時間,超過了這個時間,他們就會被系統(tǒng)強(qiáng)行終止,并且系統(tǒng)還會向你匯報該函數(shù)結(jié)束的原因是因?yàn)槌瑫r,這樣你就可以發(fā)現(xiàn)這些Bug了。要實(shí)現(xiàn)這一功能,只需要給@Test標(biāo)注加一個參數(shù)即可,代碼如下:
@Test(timeout = 1000) public void squareRoot() { calculator.squareRoot(4); assertEquals(2, calculator.getResult()); }
Timeout參數(shù)表明了你要設(shè)定的時間,單位為毫秒,因此1000就代表1秒。
測試異常
JAVA中的異常處理也是一個重點(diǎn),因此你經(jīng)常會編寫一些需要拋出異常的函數(shù)。那么,如果你覺得一個函數(shù)應(yīng)該拋出異常,但是它沒拋出,這算不算Bug呢?這當(dāng)然是Bug,并JUnit也考慮到了這一點(diǎn),來幫助我們找到這種Bug。例如,我們寫的計算器類有除法功能,如果除數(shù)是一個0,那么必然要拋出“除0異?!?。因此,我們很有必要對這些進(jìn)行測試。代碼如下:
@Test(expected = ArithmeticException.class) public void divideByZero(){ calculator.divide(0); }
如上述代碼所示,我們需要使用@Test標(biāo)注的expected屬性,將我們要檢驗(yàn)的異常傳遞給他,這樣JUnit框架就能自動幫我們檢測是否拋出了我們指定的異常。
參數(shù)化測試
我們可能遇到過這樣的函數(shù),它的參數(shù)有許多特殊值,或者說他的參數(shù)分為很多個區(qū)域。
例如,測試一下“計算一個數(shù)的平方”這個函數(shù),暫且分三類:正數(shù)、0、負(fù)數(shù)。在編寫測試的時候,至少要寫3個測試,把這3種情況都包含了,這確實(shí)是一件很麻煩的事情。測試代碼如下:
public class AdvancedTest { private static Calculator calculator = new Calculator(); @Before public void clearCalculator(){ calculator.clear(); } @Test public void square1() { calculator.square(2); assertEquals(4, calculator.getResult()); } @Test public void square2(){ calculator.square(0); assertEquals(0, calculator.getResult()); } @Test public void square3(){ calculator.square(-3); assertEquals(9, calculator.getResult()); } }
為了簡化類似的測試,JUnit4提出了“參數(shù)化測試”的概念,只寫一個測試函數(shù),把這若干種情況作為參數(shù)傳遞進(jìn)去,一次性的完成測試。代碼如下:
@RunWith(Parameterized.class) public class SquareTest{ private static Calculator calculator = new Calculator(); private int param; private int result; @Parameters public static Collection data() { return Arrays.asList(new Object[][]{ {2, 4}, {0, 0}, {-3, 9}, }); } //構(gòu)造函數(shù),對變量進(jìn)行初始化 public SquareTest(int param, int result){ this.param = param; this.result = result; } @Test public void square(){ calculator.square(param); assertEquals(result, calculator.getResult()); } }
執(zhí)行了3次該測試類,依次采用了數(shù)據(jù)集合中的數(shù)據(jù){處理值,預(yù)期處理結(jié)果},結(jié)果如下:
代碼分析如下:
- 為這種測試專門生成一個新的類,而不能與其他測試共用同一個類,此例中我們定義了一個SquareTest類。
- 為這個類指定一個Runner,而不能使用默認(rèn)的Runner,@RunWith(Parameterized.class)這條語句就是為這個類指定了一個ParameterizedRunner
- 定義一個待測試的類,并且定義兩個變量,一個用于存放參數(shù),一個用于存放期待的結(jié)果。
- 定義測試數(shù)據(jù)的集合,也就是上述的data()方法,該方法可以任意命名,但是必須使用@Parameters標(biāo)注進(jìn)行修飾。
- 定義構(gòu)造函數(shù),其功能就是對先前定義的兩個參數(shù)進(jìn)行初始化
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
springboot+jersey+tomcat實(shí)現(xiàn)跨域方式上傳文件到服務(wù)器的方式
這篇文章主要介紹了springboot+jersey+tomcat實(shí)現(xiàn)跨域方式上傳文件到服務(wù)器,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-03-03String字符串轉(zhuǎn)BigDecimal時,報NumberFormatException異常的解決
這篇文章主要介紹了String字符串轉(zhuǎn)BigDecimal時,報NumberFormatException異常的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07Java錯誤org.apache.ibatis.binding.BindingException: Inval
本文主要介紹了Java錯誤org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.sjks.mapper.Use,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06Java開發(fā)者必備10大數(shù)據(jù)工具和框架
這篇文章主要為大家詳細(xì)介紹了Java開發(fā)者必備10大數(shù)據(jù)工具和框架,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-06-06RocketMQ中消費(fèi)者概念和消費(fèi)流程詳解
這篇文章主要介紹了RocketMQ中消費(fèi)者概念和消費(fèi)流程詳解,RocketMQ是一款高性能、高可靠性的分布式消息中間件,消費(fèi)者是RocketMQ中的重要組成部分,消費(fèi)者負(fù)責(zé)從消息隊列中獲取消息并進(jìn)行處理,需要的朋友可以參考下2023-10-10基于Springboot一個注解搞定數(shù)據(jù)字典的實(shí)踐方案
這篇文章主要介紹了基于Springboot一個注解搞定數(shù)據(jù)字典問題,大致的方向是自定義注解,在序列化的時候進(jìn)行數(shù)據(jù)處理,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-06-06Vue中對象賦值問題:對象引用被保留僅部分屬性被覆蓋的解決方案
在?Vue?中,當(dāng)你直接給一個響應(yīng)式對象(如?reactive?或?ref?包裝的對象)賦新值時,如果直接使用?=?賦值,可能會遇到?對象引用被保留,僅部分屬性被覆蓋?的問題,本文給大家介紹了Vue中對象賦值問題:對象引用被保留僅部分屬性被覆蓋的解決方案,需要的朋友可以參考下2025-07-07PowerJobAutoConfiguration自動配置源碼流程解析
這篇文章主要為大家介紹了PowerJobAutoConfiguration自動配置源碼流程解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12