到底單元測試(Unit Test)要怎麼寫?這篇就直接動手做一個。
什麼是「一個單元」#
單元測試的目的是驗證一個邏輯單元是否正確。這句話裡面其實藏著兩個爭論點:什麼算一個「單元」?什麼又算「正確」?
實務上,單元測試做的事就是檢查程式碼跑起來的表現,是否與當初腦中設想的一致。至於「單元」的大小,可以由開發者自行決定:只要它「足以表達一個商業邏輯,而且僅表達這個商業邏輯」,就可以稱為單元。一旦覺得「這個測試怎麼寫起來這麼麻煩」,那恭喜你,你發現了縮小單元的時機。
一個單元測試的三件事#
不管寫法千變萬化,一個單元測試大致都是三個步驟:
- 準備資料
- 跑起來
- 檢查結果
只要這三件事在同一個測項裡面被完成,就算是一個可運作的單元測試。能反覆通過此測試的程式碼,自然也就被視為可運作的程式碼。
範例:學生姓名串接#
假設我們在做教務處網站的後端 API。系統需要把學生的姓與名串接成全名,例如 first name 是 Michael、last name 是 Jordan,全名應該是 Michael Jordan。
Student 類別可以這樣寫:
public class Student {
String lastName;
String firstName;
public Student(String firstName, String lastName) {
this.lastName = lastName;
this.firstName = firstName;
}
public String getFullName() {
return firstName + " " + lastName;
}
}接著針對「執行結果是否符合預期」寫一個測試,依照三步驟進行:
- 準備資料:建立一個
Student物件,firstName 是 Michael、lastName 是 Jordan。 - 跑起來:呼叫
getFullName()。 - 檢查結果:確認回傳值等於
"Michael Jordan"。
class StudentTest {
@Test
void full_name() {
Student student = new Student("Michael", "Jordan");
String actual = student.getFullName();
assertEquals("Michael Jordan", actual);
}
}當測試通過時,IDE 會亮起綠燈。這就是人生的第一個單元測試。日後要是有人不小心把 getFullName 的邏輯改錯,這個測項就會立刻紅起來,提醒對方該改回去。
想要再加上「lastName 為空」或「firstName 為空」的情境也很簡單,照著這個範本依樣畫葫蘆,就會是你的第二、第三個單元測試。
寫測試其實沒這麼複雜#
從這個範例可以看到,單元測試的入門門檻其實不高。準備、執行、驗證三步驟做完就是一個測項,並沒有想像中的繁瑣。「沒時間測」這個藉口,在這種尺度的測試面前其實是站不住腳的。
原文出處#
- 原書/iThome:https://ithelp.ithome.com.tw/articles/10259827