跳到主要內容跳到頁尾

Apps Script 邊界測試:運費級距改了,怎麼知道沒改壞

5 分鐘閱讀Lv.2 中級摘要與日期

以運費級距示範先定答案再改程式:先寫好每個金額的預期運費,用函式逐筆比對,把 PASS 與 FAIL 寫進測試結果分頁;邊界、文字金額、空白與負數都有案例。

發布 更新

文章目錄

訂單金額 500 元(含)以下運費 100,超過 500 到 1000 元(含)運費 60,超過 1000 元免運。規則看起來簡單,真正容易出錯的是剛好 500、剛好 1000 那兩個金額。

改運費規則時,與其改完再靠眼睛檢查,不如先把每個金額該收多少寫下來,再讓程式一次比完。這篇就是這個做法。

先看流程

概念示意:先寫好測試案例與預期運費,shippingFee 對每個金額算出實際運費,逐列比對後把 PASS 或 FAIL 寫進測試結果分頁;邊界兩側、文字金額、空白與負數都要有案例。← 左右滑動看完整的圖,點圖可放大

答案在程式之前就定好。之後不管怎麼改程式,重跑一次,就知道哪幾筆壞了。

先準備與執行

  • 在試算表選「擴充功能 → Apps Script」,把三個區塊依序貼進去並儲存。
  • 在上方函式選單選 runShippingTests,按「執行」。若 Google 要求授權,先看清楚列出的權限再同意。
  • 程式會自己建立「測試結果」分頁;「執行記錄」會顯示「通過 12/12」。

區塊一:運費規則與函式

程式碼.gs
Apps Script
/**
 * @OnlyCurrentDoc
 */

// 訂單金額 ≤500 運費 100;501 到 1000 運費 60;超過 1000 免運
const FEE_TABLE = [
  { max: 500, fee: 100 },
  { max: 1000, fee: 60 },
  { max: Infinity, fee: 0 },
];

// 回傳運費;金額無法判斷(空白、負數、不是數字)時回傳 null,不當成免運
function shippingFee(amount) {
  const isText = typeof amount === "string" && amount.trim() !== "";
  const n = typeof amount === "number" ? amount : isText ? Number(amount) : NaN;
  if (!Number.isFinite(n) || n < 0) {
    return null;
  }
  return FEE_TABLE.find((t) => n <= t.max).fee;
}
  • 最上面的 @OnlyCurrentDoc 註解,宣告這支程式只會用到目前這份試算表。
  • FEE_TABLE 由小到大排列,函式取第一個「金額 ≤ 上限」的級距。<= 就是決定「剛好 500 算哪一邊」的地方。
  • 金額無法判斷時(空白、負數、不是數字)回傳 null,不是 0。回 0 等於「免運」,錯誤資料就會被默默當成免運。
  • 儲存格裡的 "500" 可能是文字,函式先轉成數字再比。

區塊二:先定答案的測試案例

程式碼.gs
Apps Script
// 先定答案:每一筆都是「輸入」與「預期」,邊界的兩側都要有
const TEST_CASES = [
  { amount: 0, expected: 100 },
  { amount: 1, expected: 100 },
  { amount: 500, expected: 100 },
  { amount: 500.5, expected: 60 },
  { amount: 501, expected: 60 },
  { amount: 1000, expected: 60 },
  { amount: 1000.01, expected: 0 },
  { amount: 1001, expected: 0 },
  { amount: "500", expected: 100 },
  { amount: "", expected: null },
  { amount: -1, expected: null },
  { amount: "abc", expected: null },
];
  • 每一筆都是「輸入」加「預期」。邊界的兩側都要有:500 與 501、1000 與 1001。
  • 500.5 和 1000.01 檢查「剛過邊界」的小數:規則是「≤500 才是 100」,所以 500.5 算 60。
  • "500"(文字)、""(空白)、-1、"abc" 檢查輸入不是正常數字時的反應。
  • 0 元被當成最低級距、運費 100,這是這篇的決定;你的規則可能不同,就改預期。

區塊三:執行並寫成報告

程式碼.gs
Apps Script
function runShippingTests() {
  const book = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = book.getSheetByName("測試結果") || book.insertSheet("測試結果");
  sheet.clearContents();
  const show = (value) => (typeof value === "string" ? '"' + value + '"' : String(value));
  let passed = 0;
  const rows = TEST_CASES.map((testCase) => {
    const actual = shippingFee(testCase.amount);
    const ok = actual === testCase.expected;
    if (ok) {
      passed++;
    }
    return [show(testCase.amount), String(testCase.expected), String(actual), ok ? "PASS" : "FAIL"];
  });
  sheet.getRange(1, 1, rows.length + 1, 4).setValues([["輸入", "預期", "實際", "結果"]].concat(rows));
  Logger.log("通過 " + passed + "/" + rows.length);
}
  • 每一筆呼叫一次 shippingFee,和預期比對,寫成 PASS 或 FAIL。
  • 結果整張一次 setValues 寫入,不是逐格寫。
  • 每次執行先 clearContents(),可以重跑;也因此「測試結果」分頁會整張被覆寫,不要在上面放別的東西。

同一條規則,用公式寫一次

函式要驗證的規則,用公式也寫得出來。下表可以改金額,看公式算出的運費:

A2公式載入中…
列 / 欄ABC
1金額公式算出的運費
20(公式 =IF(A2<=500,100,IF(A2<=1000,60,0)),尚未計算)
31(公式 =IF(A3<=500,100,IF(A3<=1000,60,0)),尚未計算)
4500(公式 =IF(A4<=500,100,IF(A4<=1000,60,0)),尚未計算)
5500.5(公式 =IF(A5<=500,100,IF(A5<=1000,60,0)),尚未計算)
6501(公式 =IF(A6<=500,100,IF(A6<=1000,60,0)),尚未計算)
71000(公式 =IF(A7<=500,100,IF(A7<=1000,60,0)),尚未計算)
81000.01(公式 =IF(A8<=500,100,IF(A8<=1000,60,0)),尚未計算)
91001(公式 =IF(A9<=500,100,IF(A9<=1000,60,0)),尚未計算)
10
11

試試看!修改數字,公式會自動重算 • 重新整理即還原

公式適合在表格裡直接算;函式適合被別的程式呼叫,也能用同一份案例反覆驗證。

故意改錯,看測試抓不抓得到

把 FEE_TABLE.find 裡的 n <= t.max 改成 n < t.max,只差一個等號。重跑後執行記錄變成「通過 9/12」,「測試結果」分頁是:

列 / 欄ABCD
1輸入預期實際結果
20100100PASS
31100100PASS
450010060FAIL
5500.56060PASS
65016060PASS
71000600FAIL
81000.0100PASS
9100100PASS
10"500"10060FAIL
11""nullnullPASS
12-1nullnullPASS
13"abc"nullnullPASS

示範試算表

錯的剛好是 500、1000 與 "500",邊界案例立刻現形。這個表是預先寫好的結果,不會自己執行程式。

換成你的情境

  • 級距與運費:FEE_TABLE 的 max、fee。
  • 邊界算哪一邊:<= 或 <;改了,預期值也要跟著改。
  • 無效金額怎麼處理:回傳 null、改成報錯,或當成 0,由你的業務規則決定。
  • 測試案例:TEST_CASES,每個級距邊界的兩側各一筆。
1

多一個運費級距,案例怎麼改?

規則改成:500 元以下 100、501 到 1000 元 60、1001 到 2000 元 30、超過 2000 元免運。先預測:FEE_TABLE 要怎麼改?哪幾筆既有案例的預期會變?要新增哪幾筆?

延伸閱讀

分享:
#Apps Script#測試#邊界值#運費計算
喜特先生 Mr. Sheet

喜特先生 Mr. Sheet

數據分析師/商業分析師

八年工作經驗,跨不同業界解決數據需求。做過的案例都整理在作品集。

接下來可以

相關文章

查看所有文章

留言討論

共 0 則留言

訂閱電子報,新文章上線就通知你

免費,隨時可取消。

送出即表示同意服務條款與隱私權政策。