單元測試(Unit Test)在近兩年間火熱的被推行,個人推測與敏捷式開發(Agile Development)軟體方法論,不顧一切的直接式進入開發維護循環有極大的關連。今天有機會碰到一點單元測試,因此在這邊寫一篇文章記錄下來,以備不時之需。
這篇文章所有的內容是使用Java技術,因此請使用者先下載Java JRE,並且安裝好Eclipse 4.4含以上版本,這樣才可以讓你的JUnit單元測試工作可以平順的運行。
Step 1. 進入Eclipse後,點選File>New>Java Project,開啟一個新的Java專案。
Step 2. 專案的名稱取為「TestSample」。
Step 3. 在src的圖示上按右鍵,新增一個名為Calculator的class,這個類別裡面只有加法跟減法兩個簡單的方法。
public class Calculator { //加法 public double Add(double a, double b) { return a + b; } //減法 public double Sub(double a, double b) { return a - b; } }
Step 4. 在src的圖示上按右鍵,New>JUnit TestCase,做出一個單元測試用的類別。
Step 5. 只要是單元測試就是要自己寫腳本,沒有那種自己會幫你測試的事,請立即放棄這種天真的想法。圖型與程式碼如下:
//請一定要import這個Namespace import junit.framework.*; //請一定要extends這個TestCase類別 public class TestCalculator extends TestCase { public double dInput_1, dInput_2, dResult; public Calculator myCal; //起始單元測試時的方法 public void setUp() { myCal = new Calculator(); } //終止單元測試時的方法 public void tarDown() { myCal = null; } /* JUnit會自動找你這個類別裡面,所有開頭為test的方法,並且去執行它。 */ //測試加法一 public void testAdd_1() { dInput_1 = 1.0; dInput_2 = 2.0; dResult = 3.0; assertEquals(dResult, myCal.Add(dInput_1, dInput_2)); } //測試加法二 public void testAdd_2() { dInput_1 = 1.1; dInput_2 = 2.2; dResult = 3.3; assertEquals(dResult, myCal.Add(dInput_1, dInput_2)); } //測試減法 public void testSub() { dInput_1 = 3.0; dInput_2 = 2.0; dResult = 1.0; assertEquals(dResult, myCal.Sub(dInput_1, dInput_2)); } }
Step 6. 寫完了Test Case後,你就可以開始跑自動測試了,但事實上根本不是自動跑,是你自己寫的吧!請點選Run>Run As>JUnit Test。
Step 7. 如果你全部都對,那麼下圖中左上方會出現綠色,但是這張圖中出現的是紅色,這代表有問題。我們細看之下,它真的有幫我們跑完3/3個方法,Error數目也是0(如果你的程式碼有錯誤,導致編譯出錯,那麼會Error就會出現錯誤數目),所以我們觀察到引發紅色的就是Failures,它顯示有1個問題。再往下看下方的小圖示,我們可以發現testAdd_2這個方法被打X記號,表示這個跑出來跟我們預期的答案不一樣。
再往下看下方的Failure Trace的原因,我們看到它本來預期(expected)是3.3(1.1 + 2.2 = 3.3),但是Test Case跑出來的卻是3.3000000000000003,因此出錯。(至於為什麼會出現3.3000000000000003,這等一下再討論。)
Step 8. 將assertEquals這個JUnit支援的方法,調用第三個optional的argument,稱為「誤差容忍度」,將其改為0.01,這表示誤差在0.01之下是被允許的,因此該測試方法的程式碼修正如下方程式碼,再測一次就過啦!
//測試加法二 public void testAdd_2() { dInput_1 = 1.1; dInput_2 = 2.2; dResult = 3.3; assertEquals(dResult, myCal.Add(dInput_1, dInput_2), 0.01); }