iT邦幫忙

2026 iThome 鐵人賽

DAY 8
0

前言:commit message 講的,跟程式碼改的,是同一件事嗎?

「commit message 寫的是加了什麼功能,那測試就一定是為了驗證那個功能新寫的,不是嗎?」

大部分時候是這樣沒錯。但 omnipay-ecpay 裡有一筆 commit,攤開 diff 一看,commit message 講的範圍,比程式碼實際變更的範圍還大。今天先不下結論,只是把這筆 commit 完整攤開來看。

今日目標

  • 看懂 commit 80d3469 的完整 diff,分清楚哪些是真正新增的程式碼,哪些是新增的測試
  • 練習「先看 diff,再看 commit message」的核對習慣,而不是照單全收
  • 找出這筆 commit 裡「程式碼變更範圍」跟「測試變更範圍」對不上的地方
  • 為接下來兩天的討論(新功能配新測試 vs 順路補測試)打底

commit 說了什麼

commit 80d3469,2025-11-29,訊息是這樣寫的:

Add BNPL payment support and tests for ATM, BNPL, FlexibleInstallment

- Add getBNPLFields() method for BNPL (無卡分期) payment type
- Add test cases for ATM, BNPL, and FlexibleInstallment (30N) payments

翻成白話:「新增 BNPL 付款支援,並且補了 ATM、BNPL、彈性分期(FlexibleInstallment)三種情境的測試。」

git show --stat 顯示這筆 commit 只動了兩個檔案:

 src/Message/PurchaseRequest.php       |  15 ++++
 tests/Message/PurchaseRequestTest.php | 139 ++++++++++++++++++++++++++++++++++
 2 files changed, 154 insertions(+)

程式碼實際改了什麼

src/Message/PurchaseRequest.php 這 15 行新增的內容,只有一個新方法:

/**
 * BNPL 無卡分期(裕富/中租).
 *
 * @param  string  $choosePayment
 * @return array
 */
private function getBNPLFields($choosePayment)
{
    return in_array($choosePayment, ['ALL', 'BNPL'], true) ? [
        'PaymentInfoURL' => $this->getPaymentInfoURL(),
        'ClientRedirectURL' => $this->getClientRedirectURL(),
    ] : [];
}

再加上把這個方法接進原本的 getSendExtend() 組裝流程裡(一行 $this->getBNPLFields($sendFields['ChoosePayment']))。就這樣,程式碼變更的範圍只涵蓋 BNPL 這一種付款方式

測試實際改了什麼

tests/Message/PurchaseRequestTest.php 新增了 139 行,仔細看方法名稱:

public function testATMGetData() { /* ... */ }
public function testBNPLGetData() { /* ... */ }
public function testFlexibleInstallmentGetData() { /* ... */ }

三個新測試方法,涵蓋 ATM、BNPL、彈性分期三種付款情境。

對不起來的地方

程式碼變更只碰了 BNPL;測試變更卻涵蓋 ATM、BNPL、彈性分期三種。回頭去翻 src/Traits/HasATMFields.phpPurchaseRequest.php 裡處理彈性分期(CreditInstallment)的邏輯,這些程式碼不是這次新增的——getATMFields() 這個方法、CreditInstallment 相關的欄位設定,在這次 commit 之前就已經存在於程式碼裡了。

也就是說:這次 commit 真正新增的功能只有 BNPL 一種,但新增的測試涵蓋了三種——其中兩種(ATM、彈性分期)是「早就能用、但一直沒被測過」的既有功能,這次才第一次補上測試。

commit message 講的是「加了什麼」,diff 才告訴你「實際發生了什麼」——這兩者不一定是同一件事,尤其是牽涉到測試的時候。

❌ vs ✅:只看 commit message vs 對照 diff 求證

❌ 只看 commit message 得到的理解
"這筆 commit 加了 BNPL 功能,順便補了 ATM 跟彈性分期的測試"
→ 聽起來像是三個功能都是新的,測試只是「隨手」順便寫
✅ 對照 diff 之後得到的理解
"這筆 commit 只新增了 BNPL 一種付款方式的程式碼;
 ATM 跟彈性分期的程式碼其實已經存在一段時間,
 這次才第一次被寫測試覆蓋到"
→ 這代表套件裡曾經有兩條「能動但沒測過」的路徑,
   直到某次改動才被順路補上

今日思考題

你有沒有讀過一筆 commit message,後來發現實際 diff 講的故事跟 message 不完全一樣?你當時是怎麼發現的——自己去翻 diff,還是不小心踩到 bug 才回頭查?

今日重點回顧

  • commit 80d3469 的訊息涵蓋 BNPL/ATM/彈性分期三種情境的測試,但程式碼變更只涉及 BNPL 一種
  • ATM、彈性分期的程式邏輯在這次 commit 之前就已經存在,只是這次才第一次被測到
  • commit message 是作者對「這次做了什麼」的摘要,不是逐字對應 diff 的紀錄,讀 commit 要記得對照實際變更
  • 這個落差不是巧合,而是接下來兩天要拆解的「順路補測試」現象的具體證據

明日預告

明天拆解這個現象背後的兩種節奏:「新功能配新測試」跟「順路把舊功能的測試補上」,這兩種節奏在真實開發裡是怎麼交織在一起的,為什麼後者反而更貼近現場。


上一篇
Day 07:覆蓋率報表設定得很齊全,卻沒人在看
下一篇
Day 09:兩種節奏——「功能配測試」跟「順路補測試」
系列文
AI 輔助開發下,測試如何保住品質防線10
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言