全部產品
Search
文件中心

AI Coding Assistant Lingma:單元測試實踐

更新時間:Jun 07, 2025

本文首先講述了什麼是單元測試、單元測試的價值、一個好的單元測試所具備的原則,進而引入如何去編寫一個好的單元測試,靈碼是如何快速產生單元測試的。

什麼是單元測試?

單元測試是一種軟體測試方法,通過編寫代碼來驗證應用程式中最小的可測試單元(如單個函數、方法或類)的正確性。通常,單元測試由開發人員在功能實現過程中或完成後編寫,其目的是確保每個最小可測試單元都能按照設計預期正常工作。

單元測試的價值

單元測試的價值主要體現在提高軟體品質和可靠性,‌確保代碼在修改或重構後仍然能夠正常運行。‌單元測試的優勢包括:

  • 提高代碼品質:‌通過發現代碼中的錯誤和漏洞,‌從而提高代碼的品質和可靠性。‌

  • 提高開發效率:‌在開發過程中及時發現問題,‌減少開發週期和成本。‌

  • 便於重構和維護:‌確保代碼在重構和維護過程中不會出現新的錯誤和漏洞。‌

  • 有助於團隊協作:‌作為團隊成員之間的溝通和協作工具,‌提高團隊的協作效率和品質。‌

此外,‌單元測試還可以讓軟體故障儘早被發現,‌避免故障遺留到後期由於定位修複難度帶來的更大損失。‌它的可迴歸性為軟體提供了一層安全防護網,‌為軟體後續的重構和修改提供了安全保障。‌單元測試還為軟體單元如何被使用提供了天然的代碼範例使用手冊。

遵循的原則

好的單元測試就像空氣(AIR)一樣感覺不到,但在測試品質的保障上,卻是非常關鍵的。好的單元測試宏觀上來說,具有自動化(A)、獨立性(I)、可重複執行(R)的特點。

  • A: Automatic(自動化):單元測試應能被自動化執行,以便在代碼更改時快速確認新加入的代碼沒有破壞已有功能,通常情況下會將單測接入到持續整合中,每當代碼有變更時都會通過持續整合自動觸發單元測試。

  • I: Independent(獨立性):每個單元測試應當是獨立的,不能依賴於其他測試的執行順序或結果。這也要求單測的測試顆粒度必須足夠小,只有這樣才能滿足獨立性。

  • R: Repeatable(可重複執行):好的單元測試在同樣的條件下,每次運行應當給出相同的結果。它不應依賴於外部因素(如網路、資料庫或檔案系統),需要對這些外部的依賴進行正確的mock 。

除此之外,好的單測還必須要滿足有明確的斷言,執行速度快,邊界測試充分,覆蓋率高等特點。只有滿足這些條件的單測才是好的單測,好的單元測試是對代碼品質保障至關重要的一環。

如何編寫單元測試?

下面以Java語言為例來介紹如何編寫單元測試,總體遵循以下幾個步驟:

拆分詳細的測試案例

考慮分支條件

在編寫單元測試時,需要考慮代碼中的所有分支。分支包括if、else、switch語句等,每個分支都需要單獨測試。例如:

public String classifyNumber(int number) {
    if (number < 0) {
        return "negative";
    } else if (number == 0) {
        return "zero";
    } else {
        return "positive";
    }
}

在上述代碼中,有三個分支需要測試:

  • number<0。

  • number==0。

  • number>0。

針對每個分支,都需要編寫一個測試案例。

尋找邊界條件

除了分支,還需要考慮邊界條件。例如,對於上述分類函數,邊界值是-1、0和1。邊界條件測試可以找出可能潛在的問題,確保代碼在極限條件下也能正常工作。

制定統一的單測規範

命名規範

單元測試類通常採用類名Test的形式。例如,如果要測試一個Calculator類,則單元測試類可以命名為CalculatorTest。單元測試方法的命名應當描述具體要測試的內容。例如:

public class CalculatorTest {
    @Test
    public void testAddition() {
        // 測試內容
    }
    @Test
    public void testSubtraction() {
        // 測試內容
    }
}

存放路徑

一般情況下,單元測試類存放的位置在與被測試類別相同包名的下面,但在不同的目錄中。在標準的 Maven 專案結構中,原始碼放在src/main/java,單元測試代碼放在src/test/java。

src/main/java/com/example/Calculator.java
src/test/java/com/example/CalculatorTest.java

選擇合適的單測架構

Java 常用的單元測試架構有JUnit和Mockito,下面將圍繞如何使用這兩種架構編寫基本的單元測試:

JUnit 測試架構

JUnit是Java語言中最著名的單元測試架構。它簡潔易用,提供了豐富的註解和斷言。

  1. 添加JUnit依賴(以Maven為例):

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13.2</version>
      <scope>test</scope>
    </dependency>
  2. 編寫單元測試:

    import org.junit.Test;
    import static org.junit.Assert.*;
    
    public class CalculatorTest {
        @Test
        public void testAddition() {
            Calculator calculator = new Calculator();
            assertEquals(5, calculator.add(2, 3));
        }
    }

Mockito 測試架構

Mockito是一個強大的類比架構,用於建立虛擬對象,簡化單元測試,特別是在測試不易建立的依賴對象時非常有用。

  1. 添加Mockito依賴:

    <dependency>
      <groupId>org.mockito</groupId>
      <artifactId>mockito-core</artifactId>
      <version>3.11.2</version>
      <scope>test</scope>
    </dependency>
  2. 編寫單元測試:

    import static org.mockito.Mockito.*;
    import org.junit.Test;
    
    public class UserServiceTest {
        @Test
        public void testGetUser() {
            UserService userService = new UserService();
            UserRepository mockRepo = mock(UserRepository.class);
    
            when(mockRepo.findUserById(1)).thenReturn(new User(1, "John Doe"));
            userService.setUserRepository(mockRepo);
    
            User user = userService.getUserById(1);
            assertNotNull(user);
            assertEquals("John Doe", user.getName());
        }
    }

如何使用靈碼快速產生單測

在大多數開發人員的編程習慣中,通常採用Test Later的方法進行單元測試,即首先編寫好代碼,然後再為代碼編寫相應的單元測試。在此背景下,利用靈碼產生單元測試顯得尤為便捷。以下列舉幾種使用靈碼產生單元測試的方式。

手工選中代碼方式產生

在 IDE 編輯區中,通過靈碼選中某段代碼來產生單測,選中代碼後,在靈碼的問答框內,通過 /unittest來產生與選中的代碼對應的單元測試。

整屏樣本@1x (5)

說明

使用/unittest這個命令時,可以在輸入框追加更多的資訊,來產生更符合開發人員需要的測試案例,如需要支援JUnit5或採用Mockito進行Mock,就可以採用 /unittestJUnit5Mockito這樣的方式,後面兩個關鍵詞被當作前面命令的參數,這樣的使用方式,同樣適用於其他命令。

使用快捷按鈕方式產生

靈碼每個方法簽名的上面都會有一個小表徵圖,單擊表徵圖後會彈出相應的命令菜單,選擇產生單元測試。

整屏樣本@1x (7)

也可以選擇要產生的程式碼塊,然後單擊右鍵來選擇產生單元測試功能。

整屏樣本@1x (9)

採納單元測試

單測代碼產生完畢後,在問答區的代碼塊右上方,會有三個選項,分別是插入代碼,複製和建立檔案:

  • 插入代碼:會將當前產生的單測代碼插入到當前開啟的檔案中。

  • 複製:即複製代碼塊的代碼,由使用者自行選擇將代碼複製到哪個檔案中。

  • 建立檔案:會按照Java單測的規範,新產生一個單測類檔案,放到指定的目錄中(對應單測方法檔案所在的test目錄下),如果已經存在同名的單測檔案,需要使用者自主確認是否覆蓋原檔案。

整屏樣本@1x (10)

單測產生追問

如果您對當前產生的單測代碼不滿意(需要使用特定的單測架構或者產生更多的單測方法),只需在問答區中的輸入框輸入相應的文本進行追問即可,或者也可以單擊預置的單測追問Tag,如樣本中追問的Tag :RetryUse MockitoUse Spring TestExplain code,進行追問,直到產生您滿意的單測代碼為止。

整屏樣本@1x (11)

說明

一般根據代碼產生的單元測試,會枚舉常用的測試案例,並不會遍曆所有的用例。如果您覺得產生的用例不足,建議先採納當前產生的幾個用例,放到測試檔案當中。然後,切換到測試檔案中,採用代碼續寫的方式,靈碼會協助您續寫新的測試案例。

結語

單元測試是重要的編程實踐,為編碼過程搭建品質圍欄。同時,採用測試驅動開發實踐中的Test First ,能夠顯著推動代碼設計的演變。靈碼,可以極大降低單元測試架構的搭建和測試案例編寫的工作量。同時,使用靈碼對單元測試用例保鮮,可以顯著提升編碼品質。