教師公積金計算是經典的「多條件分支+邊界值+循環輸入驗證」綜合案例。本文基於需求文檔,演示如何完成程序實現、流程圖繪製、六大覆蓋標準測試用例設計、基本路徑測試,並給出可直接落地的測試報告模板。
基礎工資 = 1500
值班收入 = D × 60
監考收入 = I × 30
上課收入 = C × 64
績效工資 = 值班收入 + 監考收入 + 上課收入
工資總額 = 基礎工資 + 績效工資
公積金 = 分段累進計算:
總額 > 5000: (總額-5000)×0.25 + 1000×0.2 + 2000×0.15 + 2000×0.1
4000 < 總額 ≤ 5000: (總額-4000)×0.2 + 2000×0.15 + 2000×0.1
2000 < 總額 ≤ 4000: (總額-2000)×0.15 + 2000×0.1
總額 ≤ 2000: 總額 × 0.1
// 通用整數輸入驗證函數
int readValidInt(const char* prompt, int min, int max) {
char buf[64];
while (1) {
printf("%s", prompt);
if (!fgets(buf, sizeof(buf), stdin)) exit(1);
buf[strcspn(buf, "\n")] = '\0';
// 字符合法性
char* p = buf;
if (*p == '+' || *p == '-') p++;
if (*p == '\0') { puts("請輸入整數"); continue; }
for (; *p; p++) if (!isdigit(*p)) { puts("請輸入整數"); goto next; }
// 範圍解析
errno = 0;
long val = strtol(buf, NULL, 10);
if (errno == ERANGE || val < min || val > max) {
printf("請輸入 %d 到 %d 之間的整數\n", min, max);
continue;
}
return (int)val;
next: continue;
}
}
// 主流程調用
int duty = readValidInt("值班天數(5-22):", 5, 22);
int invigilate = readValidInt("監考次數(0-10):", 0, 10);
int classCnt = readValidInt("上課次數(0-30):", 0, 30);
程序控制流圖節點編號:
1. start
2. read duty (循環直到合法)
3. read invigilate (循環直到合法)
4. read class (循環直到合法)
5. calc performance
6. calc total
7. if total > 5000
8. reserve = formula1
9. else if total > 4000
10. reserve = formula2
11. else if total > 2000
12. reserve = formula3
13. else
14. reserve = formula4
15. output
16. end
| 路徑編號 | 路徑節點序列 | 測試數據(D,I,C) | 預期總額區間 |
|---|---|---|---|
| P1 | 1-2-3-4-5-6-7-8-15-16 | (22,10,30) | >5000 |
| P2 | 1-2-3-4-5-6-7-9-10-15-16 | (20,5,15) | 4000-5000 |
| P3 | 1-2-3-4-5-6-7-9-11-12-15-16 | (10,3,5) | 2000-4000 |
| P4 | 1-2-3-4-5-6-7-9-11-13-14-15-16 | (5,0,0) | ≤2000 |
| P5 | 1-2(非法重輸)-3-4-5-6-7-8-15-16 | (輸入abc後22,10,30) | >5000 |
目標:每條可執行語句至少執行一次
目標:每個判定的真/假分支至少各一次
| 判定點 | 真分支用例 | 假分支用例 |
|---|---|---|
| duty合法性 | (22,*,*) | (輸入abc, 後輸入22) |
| invigilate合法性 | (*,10,*) | (*,輸入xyz, 後10) |
| class合法性 | (*,*,30) | (*,*,輸入err, 後30) |
| total>5000 | (22,10,30) | (20,5,15) |
| total>4000 | (20,5,15) | (10,3,5) |
| total>2000 | (10,3,5) | (5,0,0) |
目標:每個判定中的原子條件取真/假各一次
// 判定:duty >= 5 && duty <= 22
// 原子條件:C1: duty>=5, C2: duty<=22
用例:(4,*,*) → C1假,C2真
用例:(23,*,*) → C1真,C2假
用例:(10,*,*) → C1真,C2真
同時滿足DC和CC,上述用例組合即可。
每個判定的所有原子條件組合至少一次
| 判定 | 組合 | 用例數據 |
|---|---|---|
| duty範圍 | C1假,C2真 | duty=4 |
| C1真,C2假 | duty=23 | |
| C1真,C2真 | duty=10 | |
| C1假,C2假 | duty=3 (不可能,但邏輯上存在) |
使用上述P1-P5五條獨立路徑,對應五組測試用例。
# 白盒測試報告 - 教師公積金計算系統
## 1. 測試基線
- 被測版本: v1.0 (salary.c)
- 測試環境: GCC 11.2 / Ubuntu 22.04
- 覆蓋率工具: gcov + lcov
## 2. 覆蓋率結果
| 覆蓋標準 | 目標 | 實際 | 狀態 |
|----------|------|------|------|
| 語句覆蓋 | 100% | 100% | 通過 |
| 判定覆蓋 | 100% | 100% | 通過 |
| 條件覆蓋 | 100% | 100% | 通過 |
| 路徑覆蓋 | 100% | 100% | 通過 |
## 3. 缺陷記錄
| ID | 嚴重級 | 描述 | 狀態 |
|----|--------|------|------|
| B-001 | Minor | 輸入緩衝區未清理導致連續非法輸入死循環 | 已修復 |
| B-002 | Major | 公積金公式邊界5000歸屬邏輯與需求不符 | 已修復 |
## 4. 結論
滿足所有白盒覆蓋標準,建議發布。
| 輸入 | 有效等價類 | 無效等價類 | 邊界值 |
|---|---|---|---|
| 值班天數 | [5,22] | <5, >22, 非整數 | 4,5,6, 21,22,23 |
| 監考次數 | [0,10] | <0, >10, 非整數 | -1,0,1, 9,10,11 |
| 上課次數 | [0,30] | <0, >30, 非整數 | -1,0,1, 29,30,31 |
白盒測試驗證「代碼寫對了」,黑盒測試驗證「需求滿足了」。兩者結合,構建完整質量保證體系。