生活分享
Claude Code|真正走完一次重現、失敗測試與修正
定位跨資料層及介面層的待辦狀態錯誤。點了第一筆待辦,卻改到另一筆,這種問題不能只靠一句「請修好」驗證。本篇從瀏覽器重現開始,寫出修正前會失敗的行為測試,再讓 Claude 做最小修改。最後保留同一個測試由紅轉綠的紀錄,以及相鄰情境沒有退步的證據。
閱讀時間約 6 分鐘

進階 · CLI / Desktop / VS Code / JetBrains
點了第一筆待辦,卻改到另一筆,這種問題不能只靠一句「請修好」驗證。本篇從瀏覽器重現開始,寫出修正前會失敗的行為測試,再讓 Claude 做最小修改。最後保留同一個測試由紅轉綠的紀錄,以及相鄰情境沒有退步的證據。
先讀除錯與補測試Claude Code|除錯與補測試從重現問題走到修正與回歸測試。這篇用一個刻意準備的待辦錯誤,示範如何把症狀轉成重現步驟、定位原因、補測試並驗證修正。材料中的問題是勾選一筆待辦時改到其他項目;你會先看到預期失敗,再確認修正後同一案例通過,避免只憑「看起來正常」就結束除錯。閱讀全文及待辦完整實作Claude Code|完整實作:待辦清單網站從需求到功能、測試與瀏覽器成果檢查。這篇把前面的小練習串成一個完整待辦網站:需求、介面、資料操作、篩選、本機儲存與測試。你可以直接下載材料開始,不必先完成前五十四篇。最後交付的不只是一張畫面,而是可啟動的檔案、可重跑的測試,以及清楚記錄的限制。閱讀全文。下載第 85 篇材料,務必使用 starter。它刻意含錯誤,核心測試預期失敗;reference 才是修正參考。需要 Node.js 22,閱讀約 20 分鐘,實作約 45 分鐘。
先用最少輸入重現使用者問題
閱讀完整文字說明
真正走完一次重現、失敗測試與修正,以流程和文件圖形呈現教學重點。
在 starter 執行 node server.mjs,開啟終端機顯示的本機網址。新增兩筆相同標題的待辦,依序點第一筆的完成控制。觀察被點的項目是否改變、另一筆是否被影響,再保存操作順序及實際畫面。不要只截一張最後畫面,因為它無法說明哪個動作造成錯誤。
node server.mjs
若瀏覽器保留前次 localStorage,先使用新的測試瀏覽器情境,或只清除此本機課程網站的資料。不要清除整個瀏覽器的所有網站儲存。重現資料應固定為兩筆同名、不同 id,避免每次使用不同初始內容。
記錄預期與實際:預期只有指定 id 的 completed 翻轉,實際卻改到其他項目。標題相同不是錯誤原因,而是幫助檢查程式是否依穩定 id 辨識。接著停止本次服務,回到資料層縮小重現,避免一開始就重寫 UI。
用真正的資料函式建立失敗測試
先執行原有四個模型測試,確認指定案例失敗。再建立更清楚的兩筆同名資料測試,直接匯入 model.js 的 toggleTodo。不要 mock 掉正在調查的函式,再讓假實作回傳你希望的答案;那樣測試即使通過,也沒有檢查真正錯誤。
import test from 'node:test';
import assert from 'node:assert/strict';
import {toggleTodo} from '../model.js';
test('只切換指定 id 並保留其他同名項目',()=>{
const items=[
{id:'a',title:'相同標題',completed:false},
{id:'b',title:'相同標題',completed:true}
];
const before=structuredClone(items);
const result=toggleTodo(items,'a');
assert.deepEqual(result.map(x=>[x.id,x.completed]),[['a',true],['b',true]]);
assert.deepEqual(items,before);
});
node --test tests/toggle-regression.test.mjs
預期此時非零退出,斷言顯示實際資料與預期不同。這是測試成功捕捉故障,不是要求你先把 expected 改成錯誤輸出來讓它變綠。保存命令、退出碼與關鍵差異,稍後使用完全相同的測試再跑一次。
測試描述行為,不需要把程式裡的比較式原封不動複製到斷言。使用固定輸入與外部可觀察結果,才可能在實作換一種寫法時仍提供保護。原始陣列不變也是契約,因此一併檢查。
把完整重現交給 Claude
提供瀏覽器步驟、失敗測試與允許修改的檔案。請 Claude 先讀取根因,再提出最小修改,不同時加新功能或重構。你已經有可以重現的失敗,這時不需要長篇猜測或要求它一次改完整個網站。
點選第一筆同名待辦時,另一筆也受到影響。
tests/toggle-regression.test.mjs 已在修正前失敗。
請讀取 model.js 和相關測試,指出具體根因,做最小修正。
保留測試的預期行為,不刪測試、不改成符合錯誤輸出。
修正後執行同一測試與原有模型測試,回報實際結果。
本課故障是 toggleTodo 的 id 比較被反轉。修正應讓指定 id 符合時才翻轉 completed,其他項目保留。審查差異時確認沒有順便改標題、儲存格式或 UI 控制;若需要其他修改,先用新的證據說明原因。
不要把模型解釋當成唯一根因證據。最重要的是同一輸入、同一斷言在修正後通過,而且改動與行為有直接關係。若它提出大量改寫卻無法說明哪一行修正了問題,先縮小變更再驗證。
保存綠燈與相鄰回歸案例
執行新測試與原有核心測試,預期全部通過。再增加未知 id 的案例,確認找不到項目時不會翻轉任何資料;也檢查空陣列。這些情境與原錯誤相鄰,可以防止最小修正只對特定 a、b 資料硬編碼。
node --test tests/toggle-regression.test.mjs tests/model.test.mjs
import test from 'node:test';
import assert from 'node:assert/strict';
import {toggleTodo} from '../model.js';
test('未知 id 與空陣列保持資料不變',()=>{
const items=[{id:'a',title:'A',completed:false}];
assert.deepEqual(toggleTodo(items,'missing'),items);
assert.deepEqual(toggleTodo([],'missing'),[]);
});
如果原有測試仍失敗,先查看是否同一根因或另一個問題,不使用跳過測試掩蓋結果。若發現既有測試和正式需求矛盾,將矛盾明列並查證;不能因為測試有名字就推定它永遠代表正確規格。
回到瀏覽器核對完整路徑
重新啟動服務,使用與第一輪相同的兩筆同名資料與點擊順序。確認第一筆正確切換,第二筆保持原狀,切回與刪除操作也正常。資料測試通過代表資料函式符合案例,但 UI 可能仍綁到錯誤 id,因此瀏覽器重驗不可省略。
紀錄視窗寬度與操作方式。若使用手機寬度,確認控制項可點擊、狀態可辨認且沒有水平撐寬。這裡只驗證你實際測過的畫面,不把一個桌面截圖寫成所有裝置已驗收。測試結束後停止本次服務。
在 Git 差異確認修正與測試都被保存,輸出檔沒有包含無關私人內容。你可以保留紅燈與綠燈的文字紀錄,不需保留每次重跑的完整大檔。重點是讓另一位讀者能辨認修正前後使用相同測試。
用三層證據避免修錯位置
除錯時保留三層證據:使用者動作、資料函式結果、程式差異。第一層說明誰受到影響,第二層把問題縮小到固定輸入,第三層解釋修正如何改變結果。如果只有第三層的一行比較式,別人可能不知道原來的錯誤何時發生;如果只有畫面,則難以確認修正是處理根因還是隱藏症狀。
在本課中,把第一筆資料命名為 a,第二筆命名為 b,保存修正前後的 completed 值。點擊 a 之後,應只改變 a。接著點擊 b,再核對同樣的條件。這樣比只測第一筆更能揭露硬編碼或索引綁定的問題,也能讓測試報告與瀏覽器操作使用一致的語言。
若新測試在故障版本就通過,先停下來檢查匯入路徑、測試是否真的執行,以及資料是否足以觸發錯誤。常見原因是執行到 reference、測試檔沒有被命令包含,或只用一筆資料看不到另一筆遭修改。不要直接進入修正,否則失去紅燈證據後,就無法確認測試是否有保護力。
交付時用一句話描述根因與行為,例如「id 比較相反,導致非目標項目被切換;現在只更新指定 id」。這個描述要能由差異和測試共同支持。若仍有其他未重現問題,另外列為待調查,不把它們一起標成已修復。
另外測試連續點同一筆兩次,完成狀態應回到起點,其他項目保持原樣。這個案例檢查的是翻轉操作的連續使用,不是只確認第一次點擊。若資料函式通過而畫面不變,查看是否仍使用舊狀態渲染;若畫面正確但重新整理後錯誤,則轉向儲存與載入流程,不再反覆修改已通過的比較式。
故障練習:拆穿沒有保護力的測試
把測試暫時改成只確認 result 是陣列,再對故障版本執行。它很可能通過,但沒有驗證哪筆資料被改動。恢復完整斷言,應再次捕捉錯誤。這個比較說明測試數量不等於測試品質,關鍵是斷言是否連到使用者行為。
另一個反例是把 toggleTodo 換成測試中的假函式,直接回傳預期資料。這測到的是你寫的假答案,不是正式程式。理解後立即恢復真正匯入,不把示範性的弱測試留在交付成果中。
| 證據 | 能證明的事 | 不能取代 |
|---|---|---|
| 瀏覽器重現 | 使用者路徑確實有問題 | 根因定位 |
| 修正前失敗測試 | 案例能捕捉故障 | 修正已完成 |
| 同一測試轉綠 | 最小修正符合案例 | 未涵蓋情境 |
| 瀏覽器重新操作 | UI 與資料串接正常 | 所有平台完整驗證 |
完成判準是重現步驟、紅綠紀錄、最小差異、相鄰案例與瀏覽器重驗都對得上。小練習是把同一份流程用在未知 id 的問題,先寫失敗條件再修正。接下來可練習舊專案重構Claude Code|接手缺測試舊專案:先留住行為再重構用小步變更拆出可測試模組。舊程式重複很多,不代表可以一口氣改寫後再看結果。本篇先記錄待辦統計的既有行為,補上能保護空資料、混合狀態及同名項目的測試,再分三個小差異整理模組。每一步都能說明保留了什麼,以及出問題時如何回復。閱讀全文,學會在保持既有行為的前提下整理程式。
回 Claude Code 教學總目錄Claude Code 完整教學目錄:從入門到自動化依平台、程度與功能找到需要的教學,從 96 篇文章與共用練習專案逐步完成操作。這個教學中心把 Claude Code 分成 96 個可以獨立閱讀的小題目,從桌面、CLI、網頁與手機開始,再學 MD 規則、常用指令、Skills、MCP 與自動化。你可以依推薦路線循序學習,也可以直接搜尋正在遇到的功能、命令或檔名。目錄依目前公開狀態顯示可閱讀文章。閱讀全文
同主題延伸閱讀
生活分享
Claude Code|建立第一個 mod:在 Claude Code 行程內數工具呼叫
寫一個三檔案的 mod,用驗證器與測試確認它掛上的事件。文件把 mod 定義成多了入口檔的 plugin:入口檔叫 hooks module,Claude Code 在事件發生時呼叫裡面的函式,函式可以觀察、改寫或接手事件。
生活分享
Claude Code|Git Worktree 平行工作
隔離多個任務的檔案與分支。Git Worktree 讓同一儲存庫擁有多個工作目錄,各自使用分支與檔案。本篇會把待辦篩選與文件整理分開,確認兩個 session 不會直接改到彼此的檔案,再把其中一個成果整合回主分支。你也會知道何時可以安全清理工作目錄。
生活分享
Claude Code|雙 Worktree 實作與衝突整合
隔離兩項功能,最後完成整合與回歸。兩個 Claude 工作階段同時編輯專案,最容易出現的問題是互相改到同一份檔案,或各自測試通過、整合後卻失敗。本篇用兩個 Worktree 分別處理篩選預設值與介面文字,故意製造一次小衝突,再完成整合、驗證與清理。你不需要先啟用 Agent Teams。
生活分享
Claude Code|比較流程品質、用量與執行時間
以同一資料集比較兩種工作方法。比較兩種 Claude 工作方法時,不能只挑成功那一次,也不能只看第一個答案有多快。本篇用固定案例、原始紀錄和一致判準,比較品質、重試、等待與人工整合時間,最後寫出有樣本數與限制的報告,而不是保證某個方法一定省錢。
引用本文的文章
最新旅遊情報攻略

情報
2026 韓國楓葉預測:雪嶽山 10 月 20 日、首爾近郊 10 月底、內藏山與漢拏山 11 月上旬
韓國山林廳 2026 年 9 月 22 日公布的楓紅高峰預測:雪嶽山 10 月 20 日,春川、國立樹木園到首爾植物園落在 10 月 28 日到 11 月 2 日,內藏山 11 月 4 日、漢拏山 11 月 6 日,整體比最近 5 年晚約 0.8 天。整理各地楓樹與銀杏的預測日、首爾出發怎麼排,以及出發前去哪裡看即時楓況。2026 年 10 月查證。
- 季節活動
- 自然
- 觀景

攻略胡志明市
胡志明市到頭頓一日遊:白藤碼頭搭高速船、船票與班次,下船就是胡梅纜車與耶穌基督像
人在胡志明市挪一天去頭頓看海:市中心的白藤高速船碼頭搭船,航程 120 分鐘到頭頓的胡梅碼頭,平日成人 320,000 越南盾、週末 350,000,回程末班平日 15:00。下船就是胡梅纜車站,同一條路上有白宮,小山頂上是耶穌基督像。平日一天只有兩班船,整天要從末班船倒推著排。
- 交通
- 行程範例
- 海灘

攻略沖繩
沖繩不開車攻略:單軌只到浦添,美麗海水族館要坐兩個多小時的巴士,回那霸的最後一班直達車 17:22 就開走
不租車的沖繩怎麼移動:那霸市區靠沖繩都市單軌電車(ゆいレール),那霸機場站到終點てだこ浦西 19 站、17 公里、37 分鐘,一日券 1,000 日圓;美麗海水族館有那霸機場直達的高速巴士,單程 2,000 日圓起、官方時刻表上 2 小時上下,下車後還要走 10 分鐘;古宇利島要在今帰仁村役場轉車,當天來回光坐車就六個半小時;回程的最後一班直達車 17:22 就從記念公園前開走(2026 年 9 月查證)。
- 交通
- 行程範例
- 預算