iT邦幫忙

2026 iThome 鐵人賽

DAY 1
0
IT Operation

AI 輔助開發下,測試如何保住品質防線系列 第 1

Day 01:AI 幫你寫更多程式碼,但品質防線要自己蓋

  • 分享至 

  • xImage
  •  

前言:AI 能補程式碼,但補不出你沒發現的缺口

「現在 AI 這麼厲害,寫測試不是應該叫 AI 順手補一補就好了嗎?」

如果你也這樣想過,這個系列想用一個真實存在、你可以直接打開來看的公開 PHP 套件,回答這個問題——不是空談「AI 寫的測試不可靠」這種老生常談,而是給你看具體發生過什麼事

素材是 omnipay-taiwan/omnipay-ecpay,一個讓 Omnipay 支付抽象層可以接上台灣綠界金流(ECPay)的驅動套件,我自己維護。這個系列會直接翻它的 commit 歷史、測試檔案、CI 設定,找出真實的品質防線長什麼樣子——包括防線上真實存在的破洞。

今日目標

讀完這篇你會知道:

  • 這個系列要用什麼專案當素材,為什麼選它
  • 什麼是「品質防線」,在一個公開套件裡它具體長什麼樣子(不是抽象概念)
  • 這個套件目前測試現況的幾個關鍵數字
  • 這個系列會分幾個階段展開,分別在講什麼
  • 貫穿全系列的一句話:AI 能幫你補程式碼,但補不出你自己都沒發現的測試缺口

為什麼選一個公開套件當素材

跟我另一個系列(用一套去識別化的 legacy 系統當素材)不一樣,這次刻意選一個任何人都能打開來看的公開專案。原因很直接:品質防線這種東西,講得再抽象都不如直接把 commit diff 攤開來看。你現在就可以打開瀏覽器去對照我接下來每一篇提到的檔案跟行號,這是去識別化素材做不到的事。

也因為這樣,這個系列不能唬爛——每個論點都要能被你反查證實。

一個公開套件的品質防線,實際長什麼樣子

先講幾個核實過的數字,讓你有個底:

  • 套件從 2021-03-25 第一個 commit 到現在,累積 36 個 commit
  • 測試檔案 6 個類別,套件自己寫的測試方法有 21 個;但實際跑 phpunit 時會執行 47 個測試——另外 26 個是從 Omnipay 官方 GatewayTestCase 基底類別自動繼承來的泛用測試(例如「每個 Gateway 都要能回傳非空名稱」「預設參數要有對應的 getter/setter」),這是這系列後面會提到的一個重點:用官方測試框架的基底類別,可以不用自己動手就先擋住一整層最基本的規範
  • CI 跑在 GitHub Actions,PHP 版本矩陣涵蓋 7.1 到 8.3
  • phpunit.xml 裡設定了完整的覆蓋率報表輸出(clover、HTML、text),但 CI 實際執行時用 --no-coverage 把它關掉了

光看這四個數字,你大概已經猜到這個系列想講什麼:這個套件不是沒有品質工具,是工具擺在那裡沒有真的被用起來守門。覆蓋率設定存在,但沒人在 CI 上盯著數字;測試存在,但覆蓋不均——有些付款方式測得很細,有些只測了一種情境。

❌ vs ✅:README 說的,跟測試證明的

這個套件的 README 現在還停留在 Omnipay 官方骨架套件的範本文字:

❌ README.md 目前的樣子
## Usage
The following gateways are provided by this package:
* ecpay

一行字,沒有告訴你這個套件實際支援信用卡、ATM、超商代碼/條碼、電子發票、還是無卡分期這些付款方式裡的哪幾種。

但如果你去看 tests/Message/PurchaseRequestTest.php,會看到:

✅ 測試案例反而說明了真正的功能範圍
public function testGetData() { /* ChoosePayment = Credit:信用卡 */ }
public function testATMGetData() { /* ChoosePayment = ATM */ }
public function testBNPLGetData() { /* ChoosePayment = BNPL:無卡分期 */ }
public function testFlexibleInstallmentGetData() { /* CreditInstallment = '30N':信用卡彈性分期 */ }

測試案例比 README 更誠實地告訴你這個套件能做什麼——這是這系列會反覆出現的一個現象:文件會過期、會被忘記更新,但測試如果寫得夠具體,會逼著你在改程式碼的同時面對「這個情境還成立嗎」的問題。這不是說測試可以取代文件,而是說當文件跟程式碼脫鉤時,測試往往是唯一還跟得上真相的東西

這個系列會怎麼展開

分四個階段,全部對應到這個套件裡已經核實過的真實案例,不是憑空設計的教學情境:

  1. 第一部(Day 1-7):認識這個套件現在的測試現況——覆蓋度為什麼不均、哪些路徑測得紮實、Trait 怎麼組合欄位、怎麼把廠商官方 SDK 包進 Omnipay 的統一介面裡
  2. 第二部(Day 8-14):拆解一筆真實 commit(80d3469),看清楚「加新功能」跟「補測試」在真實開發節奏裡是怎麼交織的——不是教科書寫的「先寫測試再寫功能」那麼乾淨,但也不是完全沒紀律
  3. 第三部(Day 15-22):跨版本相容性跟靜態品質工具——為什麼一個沒宣告 PHP 最低版本的套件,能撐住 7.1 到 8.3 的矩陣;沒有 PHPStan 的情況下,型別錯誤靠什麼擋
  4. 第四部(Day 23-30):實際動手把幾個補救動作做出來——覆蓋率門檻、被遺忘的風格檢查、AI 補功能時該怎麼被要求順手檢查測試缺口

今日思考題

你自己維護或參與過的專案裡,有沒有「工具設定了但沒人真的在看」的東西?可能是覆蓋率報表、可能是 CI 裡一個從沒被呼叫過的 lint script。先想一下,這系列後面會直接示範怎麼把這種「擺著好看」的防線變回真的有用。

今日重點回顧

  • 這個系列的素材是真實、可公開查證的 PHP 套件 omnipay-taiwan/omnipay-ecpay
  • 品質防線不是抽象概念:覆蓋率設定、CI 矩陣、測試案例分布,都是可以量化核實的具體東西
  • 測試案例本身可以是「比 README 更誠實的文件」
  • 全系列主題句:AI 能幫你補程式碼,但補不出你自己都沒發現的測試缺口

明日預告

明天會看這個套件怎麼用 Trait 組合出 12 種不同的付款方式欄位,以及這種設計在「多人共用的套件」跟「我自己接手的系統」之間,會遇到不一樣的取捨。


寫在最後:維護一個公開套件跟接手一套內部系統,最大的差別是「你看不到誰在用它」。你補的每個測試、關掉的每個覆蓋率警告,都是在替一群你素未謀面的使用者把關。這系列接下來會誠實地帶你看,這件事我自己也還沒做得完美——這正是我想把它寫成系列的原因。


下一篇
Day 02:12 個付款方式類別,怎麼用 14 個 Trait 組出來
系列文
AI 輔助開發下,測試如何保住品質防線5
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言