iT邦幫忙

2026 iThome 鐵人賽

DAY 24
0
IT Operation

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

Day 24:把 `check-style` 接進 CI,會先踩到 8 個已知的坑

  • 分享至 

  • xImage
  •  

前言:把 check-style 接進 CI,會先踩到什麼坑?

「一個 composer script 早就寫好了,接進 CI 不就是加一行 yaml 嗎?」

技術上確實只要加一行。但昨天我們已經看過「工具裝了不代表被真的打開」,今天要看的是另一種更麻煩的情況:工具一旦真的被打開,馬上就會亮紅燈——因為 Day 20 已經核實過,src/Traits/HasCVSOrBARCODEFields.php 裡有 8 個方法名稱不符合 PSR2 規範。今天實際示範接進去之後會發生什麼事,以及兩種處理方式的取捨。

提醒:以下操作都在我自己的本機暫存副本上做示範,不是對真實公開套件的正式修改。

今日目標

  • 看懂把 check-style 接進 CI 需要加哪一段 yaml
  • 實際驗證:接進去之後,CI 會不會因為那 8 個已知錯誤直接變紅
  • 理解兩種處理方式的取捨:先修好錯誤,還是先排除規則
  • 知道為什麼「先讓 CI 亮紅燈」有時候反而是比較誠實的做法

加一段 yaml,理論上就能接上

✅ 在 tests.yml 裡新增一個步驟
- name: Execute tests
  run: vendor/bin/phpunit --testdox --no-coverage

- name: Check coding style
  run: composer check-style

技術上就是這樣,check-style 這個 composer script 本來就存在(phpcs -p --standard=PSR2 src/),只差沒人在 CI 裡呼叫它。

但接上去,馬上就會撞到已知的 8 個錯誤

在我的本機暫存副本上,直接跑一次 composer check-style,得到跟 Day 20 一致的結果:

FILE: src/Traits/HasCVSOrBARCODEFields.php
FOUND 8 ERRORS AFFECTING 8 LINES
--------------------------------------------------------------------------------
  44 | ERROR | Method name "HasCVSOrBARCODEFields::setDesc_1" is not in camel caps format
  52 | ERROR | Method name "HasCVSOrBARCODEFields::getDesc_1" is not in camel caps format
  65 | ERROR | Method name "HasCVSOrBARCODEFields::setDesc_2" is not in camel caps format
  ...(Desc_2、Desc_3、Desc_4 各兩個,共 8 個)

這代表:如果今天直接把上面那段 yaml 貼進 CI,下一次 push 就會是紅燈——不是因為改動引入新問題,而是因為這 8 個錯誤本來就在那裡,只是一直沒有工具去檢查它。

兩種處理方式,取捨不一樣

選項一:先修好這 8 個方法名稱

❌ 現在:對應綠界官方欄位命名,帶底線
public function setDesc_1($value) { ... }
public function getDesc_1() { ... }
✅ 改成 PSR2 camelCase
public function setDesc1($value) { ... }
public function getDesc1() { ... }

問題是:Desc_1~Desc_4 是綠界官方 API 要求的參數名稱,這幾個 getter/setter 只是本地暫存欄位值用的(實際送出的資料還是要用官方要求的 Desc_1 這個 key),改掉方法名稱不影響送出的資料格式,但會是一個破壞性 API 變更——任何原本呼叫 ->setDesc_1(...) 的使用者程式碼都要跟著改。對一個已經發布在 Packagist、有真實使用者在用的套件來說,這種改動不是想改就能立刻改,通常要走過一輪棄用(deprecate)流程。

選項二:用 phpcs 的排除規則,暫時放過這 8 個方法

✅ 在 phpcs 規則裡明確排除這個檔案的命名規則檢查,並寫清楚原因
<rule ref="PSR2">
    <exclude name="PSR1.Methods.CamelCapsMethodName"/>
</rule>
<!-- HasCVSOrBARCODEFields.php 的 Desc_1~Desc_4 對應綠界官方欄位命名,刻意保留底線 -->

這個選項的好處是不用動到公開 API,壞處是排除規則一旦寫下去,容易變成「先擋一下,之後再說」然後就沒有之後了——跟這個套件現在 check-style 從沒被呼叫過的狀態,本質上是同一種風險,只是換了個位置繼續存在。

❌ vs ✅:直接讓 CI 先紅一次,還是先偷偷修好再接上?

❌ 先把已知問題都修掉、確定會綠燈了,才把 check-style 接進 CI
✅ 誠實接上去,讓它先紅一次,在 PR 描述裡寫清楚「這是已知的既有問題,不是這次改動造成的」,再決定要修還是要排除

正例看起來比較不體面,卻更誠實——讓工具的第一次執行結果如實反映現況,比先把現況擦乾淨再開機更能讓團隊(或未來的自己)看清楚真正的技術債有多少。如果每次要接一個新的檢查工具之前,都要先手動把所有既有違規修乾淨,很多品質工具永遠不會被真正接上去,因為「先清乾淨」這一步本身就會被無限期拖延。

今日思考題

你的專案裡有沒有「一直不敢打開的檢查工具」,因為打開了會冒出一堆既有問題?如果要接上去,你會選擇先修好還是先排除規則,為什麼?

今日重點回顧

  • 把 check-style 接進 CI,技術上只要加一段 yaml
  • 實測結果:接上去會立刻踢到 8 個已知的 PSR2 命名錯誤(setDesc_1 等帶底線的方法名稱)
  • 修好命名 vs 排除規則,取捨在於「要不要動到已發布的公開 API」
  • 讓檢查工具先誠實紅一次,往往比先手動清乾淨再開機更能反映真實狀況

明日預告

明天回到 Refund/Void——這兩個至今只有 1 個 happy-path 測試的類別,實際動手補一個例外情境測試,示範「主動補」跟第二部講過的「順路補」有什麼不一樣。


上一篇
Day 23:把 `--no-coverage` 拿掉,會發生什麼事
下一篇
Day 25:幫 Refund 補一個例外測試,只花了 13 行
系列文
AI 輔助開發下,測試如何保住品質防線 共 25 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言