首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> J2EE

JBuilder 2005 單元測試實戰:業務類別設計與測試案例分析

     編輯:J2EE

前言:為什麼需要測試先行?

在講解 JBuilder 2005 單元測試功能前,先建立兩個典型業務類別作為測試標的:分段函數類別與字串處理工具類別。這兩個類別涵蓋邊界條件判斷、例外處理、集合操作等常見業務邏輯,適合示範測試案例設計技巧。

業務類別一:分段函數 Subsection

業務規則定義

getValue(int d) 依輸入值 d 計算結果:

  • d < -2:回傳 |d|(絕對值)
  • -2 ≤ d < 2 且 d ≠ 0:回傳 d²
  • d = 0:回傳 100(特殊業務常數)
  • d ≥ 2:回傳 d³

sign(double d):符號函數,負數回傳 -1,正數回傳 1,零回傳 0。

原始碼實作(含植入缺陷)

package chapter25;

public class Subsection {
    public static int getValue(int d) {
        if (d == 0) {
            return 100;
        } else if (d < -2) {
            return Math.abs(d);
        } else if (d >= -2 && d < 2) {
            return d * d;
        } else { // d >= 2
            // 潛在 Bug:d > 32 時 d*d*d 會超過 Integer.MAX_VALUE (2,147,483,647)
            // 原開發者曾嘗試加入防護但被註解掉
            // if (d > 32) return Integer.MAX_VALUE;
            return d * d * d;
        }
    }

    public static int sign(double d) {
        if (d < 0) return -1;
        else if (d > 0) return 1;
        else return 0;
    }
}

缺陷分析

整數溢位風險:int 最大值約 21 億,d³ 當 d ≥ 1290 即溢位(1290³ = 2,146,689,000,1291³ = 2,151,685,571 超過)。原碼註解錯誤標示 32 為臨界值(實為 32³=32768 遠小於上限),顯示開發者對資料型別範圍認知不清。測試案例必須覆蓋 d = 1290, 1291, 2000 等邊界值。

業務類別二:字串處理工具 StringUtils

核心功能:string2Array()

將字串依分隔字元切割為陣列,支援修剪首尾分隔字元選項。

完整原始碼

package chapter25;

public class StringUtils {
    /** 對外公開 API */
    public static String[] string2Array(String str, char splitChar, boolean trim) {
        if (str == null) return null;
        
        String tempStr = str;
        if (trim) tempStr = trim(tempStr, splitChar); // 移除首尾分隔字元
        
        int arraySize = getCharCount(tempStr, splitChar) + 1;
        String[] result = new String[arraySize];
        
        int from = 0, end = 0;
        for (int i = 0; i < result.length; i++) {
            end = tempStr.indexOf(splitChar, from);
            if (end == -1) { // 最後一段
                result[i] = tempStr.substring(from);
                break;
            }
            result[i] = tempStr.substring(from, end);
            from = end + 1;
        }
        return result;
    }

    /** 移除字串首尾指定分隔字元 */
    private static String trim(String str, char splitChar) {
        int begin = 0, end = str.length();
        // 尋找首個非分隔字元
        for (int i = 0; i < str.length(); i++) {
            if (str.charAt(i) != splitChar) { begin = i; break; }
        }
        // 尋找尾部首個非分隔字元(反向)
        for (int i = str.length(); i > 0; i--) {
            if (str.charAt(i - 1) != splitChar) { end = i; break; }
        }
        return str.substring(begin, end);
    }

    /** 計算分隔字元出現次數 */
    private static int getCharCount(String str, char splitChar) {
        int count = 0;
        for (int i = 0; i < str.length(); i++)
            if (str.charAt(i) == splitChar) count++;
        return count;
    }
}

潛在缺陷與測試重點

場景輸入範例預期行為風險點
Null 輸入null回傳 nullNullPointerException
空字串""回傳長度 1 的陣列 [""]邊界條件
首尾分隔字元",a,b," (trim=true)["a", "b"]trim 邏輯正確性
連續分隔字元"a,,b"["a", "", "b"]空元素保留
無分隔字元"abc"["abc"]單元素陣列
全分隔字元",,," (trim=true)[""] 或 []極端邊界
Unicode 分隔字元"一、二、三" ('、')正確切割char 處理正確性

測試案例設計策略(JBuilder 2005 / JUnit 3.x 風格)

1. 等價類劃分 + 邊界值分析

針對 Subsection.getValue() 設計測試資料:

public class SubsectionTest extends TestCase {
    // 等價類:d < -2
    public void testNegativeLessThanMinus2() {
        assertEquals(5, Subsection.getValue(-5));
        assertEquals(3, Subsection.getValue(-3));
    }
    // 邊界:-2
    public void testBoundaryMinus2() {
        assertEquals(4, Subsection.getValue(-2)); // (-2)^2 = 4
    }
    // 等價類:-2 < d < 0
    public void testNegativeBetween() {
        assertEquals(1, Subsection.getValue(-1));
    }
    // 特殊值:0
    public void testZero() {
        assertEquals(100, Subsection.getValue(0));
    }
    // 等價類:0 < d < 2
    public void testPositiveLessThan2() {
        assertEquals(1, Subsection.getValue(1));
    }
    // 邊界:2
    public void testBoundary2() {
        assertEquals(8, Subsection.getValue(2)); // 2^3 = 8
    }
    // 整數溢位邊界(關鍵缺陷暴露)
    public void testOverflowBoundary() {
        assertEquals(2146689000, Subsection.getValue(1290)); // 正常
        // 1291 會溢位產生負數或錯誤值,測試可驗證實際行為
        int result = Subsection.getValue(1291);
        System.out.println("d=1291 result=" + result); // 觀察溢位結果
        // 若需修正,應在產品碼加入檢查或改用 long
    }
}

2. 參數化測試資料表驅動(JUnit 4+ 風格示意)


// StringUtils 測試資料表
@ParameterizedTest
@CsvSource({
    "null, , , true, null",
    "'', , , false, '[\"\"]'",
    "'a,b,c', ',', false, '[\"a\",\"b\",\"c\"]'",
    "'a,,b', ',', false, '[\"a\",\"\",\"b\"]'",
    "',a,b,', ',', true, '[\"a\",\"b\"]'",
    "'、', '、', true, '[\"\"]'",
})
void testString2Array(String input, char split, boolean trim, String expected) {
    // 解析 expected JSON 陣列與實際比對
}

JBuilder 2005 單元測試操作流程

  1. 專案啟用 JUnit 函式庫(Tools → Project Properties → Required Libraries)。
  2. 對業務類別右鍵 → Generate Test Case,選擇 JUnit 3.x/4.x、測試方法命名慣例(test*)。
  3. 產生骨架後,依上述策略填入斷言邏輯與測試資料。
  4. 使用 Test Runner(綠色播放圖示)執行單一測試類別或 TestSuite。
  5. 檢視綠燈/紅燈、堆疊追蹤、覆蓋率報告(需整合 Cobertura/Emma 外掛)。

總結

透過 Subsection(數學邊界/溢位)與 StringUtils(字串切割/空值/Unicode)兩個典型業務類別,展示了單元測試案例設計的核心技巧:等價類劃分、邊界值分析、極端場景覆蓋、缺陷導向測試。JBuilder 2005 整合 JUnit 提供視覺化測試執行環境,配合測試先行(TDD)流程,能在開發早期攔截如整數溢位、空指標、邊界邏輯錯誤等高風險缺陷,大幅降低後期修復成本。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved