iT邦幫忙

2021 iThome 鐵人賽

DAY 3
5

終於要開始了:「說到底,單元測試怎麼做?」

單元測試

單元測試要測的是一個邏輯單元功能是否正確。這短短的一句話,其實就有兩個蠻常爭議的點:1) 什麼叫一個單元,2) 什麼叫正確?

說到底,單元測試真正做的事,就是在驗測一段程式碼「跑起來的表現」,跟「在我腦中想像的表現」是否吻合。至於什麼叫一個單元,筆者認為,只要你認為他「足以表達一個商業邏輯,而且只表達這個商業邏輯」,就可以稱為單元。所以其實單元測試的大小,你可以自己定。一旦覺得「這個測試寫起來挺麻煩的」,那恭喜你,你找到「縮小單元」的時機點了。

單元測試的測法五花八門,但萬變不離其宗,一般來說不出三件事:

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

在一個測項裡面把這三件事做完,我們就認為,是一個 Feasible 的單元測試。而通過這個單元測試的程式(而且每次跑都會通過),自然也就被認為是 Feasible 的程式了。

以「字串串接」為例

假設我們正在維護一個「教務處網站的後端 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 的測試裡面做了三件事:

  1. 準備資料:造出 Student 物件,其 firstName 與 lastName 分別為 Michael 與 Jordan。
  2. 跑起來:呼叫 Student 的 getFullName 方法。
  3. 檢查結果:檢查回傳值是否等於 Michael Jordan。
class StudentTest {
    @Test
    void full_name() {

        Student student = new Student("Michael", "Jordan");

        String actual = student.getFullName();

        assertEquals("Michael Jordan", actual);
    }
}

一旦測試通過,你會看到IDE亮起美麗的綠燈 /images/emoticon/emoticon12.gif

至此,你的人生第一個單元測試就完成了。未來萬一有哪個冒失鬼,跑來你的程式裡把 getFullName 的邏輯改壞了,這個測項就會失敗 /images/emoticon/emoticon15.gif,對方就知道要改回來了。

什麼?你說還要測 last name 或 first name 為空的場景?那你就加呀!那就會是你人生的第二與第三個單元測試,恭喜恭喜!

謎之聲:「很簡單吧?怎麼會沒時間測,是吧?」

Reference

  1. 範例程式碼下載點:https://github.com/bearhsu2/ithelp2021.git
tags: ithelp2021

上一篇
Day 02 「住手!你想搞死 QA 嗎?」 單元測試是測試還是功能?
下一篇
Day 04 「樹頭顧乎哉」測試金字塔 之 Unit Test v.s. Integration Test
系列文
你就是都不寫測試才會沒時間:Kuma 的 30 天 Unit Test 手把手教學,從理論到實戰 (Java 篇)30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言