——JUnit 4 單元測試
學習到JUnit單元測試,我拿來測試之前寫過的一個計算器(兩個依存類:Calc.java CalcFunction.java)。代碼已放到github中。
貼出部分代碼:

1 public class Calc extends javax.swing.JFrame{ 2 3 public Calc() { 4 initComponents(); 5 } 6 7 private void initComponents() { 8 java.awt.GridBagConstraints gridBagConstraints; 9 10 setDefaultCloSEOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);11 setTitle("/u8ba1/u7b97/u5668");12 setBounds(new java.awt.Rectangle(500, 50, 0, 0));13 setResizable(false);14 15 ···//界面布局16 17 }18 //主要監聽19 ActionListener listenerEquals = new ActionListener() {20 public void actionPerformed(ActionEvent e) {21 formulaStand.setText(edit + "=");22 haspoint = false;23 String result;24 try {25 result = CalcFunction.Evaluate(edit+"=");26 } catch (Exception e1) {27 result = "syntax error";28 }29 if (Double.parseDouble(result)%1 == 0) {30 editStand.setText(String.valueOf((int)Double.parseDouble((result))));31 }else{32 editStand.setText(String.valueOf((float)Double.parseDouble((result))));33 }34 edit = "0";35 }36 }; 37 }Calc.javaGUI布局類,運行的結果如下圖:通過Botton輸入表達式,傳入CalcFunction類計算結果

這是計算器實現功能計算的類:

1 package com.school.indivodial; 2 3 import java.util.EmptyStackException; 4 import java.util.Stack; 5 6 public class CalcFunction { 7 private static String[] TrnsInToSufix(String IFX) { // PFX放后綴表達式,IFX為中綴表達式 8 String PFX[] = new String[IFX.length()]; 9 StringBuffer numBuffer = new StringBuffer();// 用來保存一個數的 10 Stack<String> s = new Stack<String>();// 放操作符 11 String a; 12 s.push("=");// 第一個為等號 13 int i = 0, j = 0; 14 char ch; 15 16 ··· // 棧操作,中綴表達式轉后綴表達式 17 18 return PFX; 19 } 20 21 public static String Evaluate(String IFX) throws Exception {// 后綴表達式求值 22 23 String PFX[] = null; 24 try { 25 PFX = TrnsInToSufix(IFX); 26 } catch (EmptyStackException e) { 27 return "syntax error"; 28 } 29 int i = 0; 30 double x1, x2, n; 31 String str; 32 Stack<String> s = new Stack<String>(); 33 while (PFX[i] != "=") { 34 str = PFX[i]; 35 switch (str.charAt(0)) { 36 case '0': 37 case '1': 38 case '2': 39 case '3': 40 case '4': 41 case '5': 42 case '6': 43 case '7': 44 case '8': 45 case '9': 46 s.push(str); 47 break; 48 case '+': 49 x1 = Double.parseDouble(s.pop()); 50 x2 = Double.parseDouble(s.pop()); 51 n = x1 + x2; 52 s.push(String.valueOf(n)); 53 break; 54 case '-': 55 x1 = Double.parseDouble(s.pop()); 56 x2 = Double.parseDouble(s.pop()); 57 n = x2 - x1; 58 s.push(String.valueOf(n)); 59 break; 60 case '×': 61 x1 = Double.parseDouble(s.pop()); 62 x2 = Double.parseDouble(s.pop()); 63 n = x1 * x2; 64 s.push(String.valueOf(n)); 65 break; 66 case '÷': 67 x1 = Double.parseDouble(s.pop()); 68 x2 = Double.parseDouble(s.pop()); 69 n = x2 / x1; 70 s.push(String.valueOf(n)); 71 break; 72 case 'o': 73 x1 = Double.parseDouble(s.pop()); 74 n = Math.log10(x1); 75 s.push(String.valueOf(n)); 76 break; 77 case 'n': 78 x1 = Double.parseDouble(s.pop()); 79 n = Math.log1p(x1); 80 s.push(String.valueOf(n)); 81 break; 82 case '/u221a'://'√' 83 x1 = Double.parseDouble(s.pop()); 84 n = Math.sqrt(x1); 85 s.push(String.valueOf(n)); 86 break;// 開方 87 case '^': 88 x1 = Double.parseDouble(s.pop()); 89 x2 = Double.parseDouble(s.pop()); 90 n = Math.pow(x2, x1); 91 s.push(String.valueOf(n)); 92 break; 93 ···//其他運算 94 95 } 96 i++; 97 } 98 String result = s.pop(); 99 return result;100 }101 102 } CalcFunction.java下面進行單元測試:測試CalcFunction類的方法計算結果是否有錯誤。
首先要在該工程下導入JUnit庫 具體做法:Build Path -> Config Build Path ... -> Add Libraries ... 選中JUnit Next-> 選擇JUnit 4 Finished
添加完成
new -> Java Test Case Name:CalcFunctionTest Next-> 選擇要測試的方法 ->finished
自動生成一個測試類CalcFunctionTest,里面包含一些空的測試用例,@Test 注解的。只需要將這些測試用例稍作修改即可使用。完整的CalcFunctionTest代碼如下:

1 package com.school.indivodial; 2 3 import static org.junit.Assert.assertEquals; 4 5 import org.junit.Test; 6 7 /** 8 * 9 * @author lendoon10 *CalcFunction類是Calc類的功能類,11 *Calc的UI輸入中綴表達式調用CalcFunction的靜態Evaluate方法計算返回結果12 */13 public class CalcFunctionTest {14 15 @Test16 public void testEvaluate_basic() throws Exception {17 Double expectedAnswer = Double.valueOf("90");18 Double actualAnswer = Double.valueOf(CalcFunction.Evaluate("100-(22+6×3)÷4="));19 assertEquals(expectedAnswer, actualAnswer);20 }21 22 @Test23 public void testEvaluate_pow() throws Exception{24 Double expectedAnswer = Double.valueOf("1024");25 Double actualAnswer = Double.valueOf(CalcFunction.Evaluate("2^10="));26 assertEquals(expectedAnswer, actualAnswer);27 }28 29 @Test30 public void testEvaluate_sqrt() throws Exception{31 Double expectedAnswer = Double.valueOf("8");32 Double actualAnswer = Double.valueOf(CalcFunction.Evaluate("√64="));33 assertEquals(expectedAnswer, actualAnswer);34 }35 36 @Test37 public void testEvaluate_cos() throws Exception{38 Double expectedAnswer = Double.valueOf("1");39 Double actualAnswer = Double.valueOf(CalcFunction.Evaluate("COS(0)="));40 assertEquals(expectedAnswer, actualAnswer);41 }42 }CalcFunctionTest.javaRun As -> JUnit Test,結果如圖:

測試顯示綠色的對號是通過的,顯示藍色叉號的,表示沒通過failure。如圖中的testEvaluate_cos測試方法。
運行失敗,進度條會變成紅褐色的,失敗有兩種情況:
處理結果與預期的有偏差(failure) 和 處理結果時,則直接拋出了異常——測試錯誤(error)
如圖:測試失敗的兩種情況
Failure 一般由單元測試使用的斷言方法判斷失敗引起,它表示在測試點發現了問題,如斷言"1" 和"1+1=";
而 error 則是由代碼異常引起,這是測試目的之外的發現,它可能產生于測試代碼本身的錯誤(測試代碼也是代碼,同樣無法保證完全沒有缺陷),也可能是被測試代碼中的一個隱藏的 bug 如圖中測試代碼傳入"1+1"沒有=,不是一個表達式,在程序運行中會報錯。
全部測試成功時,進度條是綠色的:

通過測試,現在的代碼已經比較穩定,可以作為 API 的一部分提供給其它模塊使用了。
總結:
經過對JUnit 的了解,簡單對之前寫的計算器代碼做個測試,收獲頗豐:JUnit作為最佳實踐測試任何可能的錯誤。單元測試不是用來證明您是對的,而是為了證明您沒有錯。JUnit還有更強大的功能等著我們去探索。
JUnit是一個開放源代碼的Java測試框架,用于編寫和運行可重復的測試。他是用于單元測試框架體系xUnit的一個實例(用于java語言)。它包括以下特性:1、用于測試期望結果的斷言(Assertion)2、用于共享共同測試數據的測試工具3、用于方便的組織和運行測試的測試套件4、圖形和文本的測試運行器 (源于百度百科。相對于百科,wiki百科要簡潔得多)
新聞熱點
疑難解答