到底單元測試(Unit Test)要怎麼寫?這篇就直接動手做一個。

什麼是「一個單元」#

單元測試的目的是驗證一個邏輯單元是否正確。這句話裡面其實藏著兩個爭論點:什麼算一個「單元」?什麼又算「正確」?

實務上,單元測試做的事就是檢查程式碼跑起來的表現,是否與當初腦中設想的一致。至於「單元」的大小,可以由開發者自行決定:只要它「足以表達一個商業邏輯,而且僅表達這個商業邏輯」,就可以稱為單元。一旦覺得「這個測試怎麼寫起來這麼麻煩」,那恭喜你,你發現了縮小單元的時機。

一個單元測試的三件事#

不管寫法千變萬化,一個單元測試大致都是三個步驟:

  1. 準備資料
  2. 跑起來
  3. 檢查結果

只要這三件事在同一個測項裡面被完成,就算是一個可運作的單元測試。能反覆通過此測試的程式碼,自然也就被視為可運作的程式碼。

範例:學生姓名串接#

假設我們在做教務處網站的後端 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