Day23 把 User Story 整理成 Test Case,再將其中一部分變成自動化測試。後端單元測試與整合測試、前端 Vitest 與 Playwright 都顯示通過,照理說可以放心了吧?
實際開啟網站操作後,仍可能遇到測試報告沒有指出的問題。功能雖然能執行,操作方式卻不符合原本的使用情境;畫面也提供了看似能修改、實際上不該讓使用者執行的選項。
這不是自動化測試沒有用。自動化測試像一位照著清單巡邏的警衛,會快速而且穩定地檢查已知規則;手動測試則像第一次來到現場的使用者,會注意按鈕找不找得到、流程順不順,以及畫面是不是容易讓人做錯事。兩種測試看到的是不同問題。
這一篇會真的啟動 SQL Server、ASP.NET Core Web API 與 Vue 前端,再從使用者角度走過主要流程。
專案經過幾輪開發後,啟動指令可能已經和最初不同。與其靠印象拼指令,可先請 Codex 讀取目前的 README.md 與設定檔:
請先閱讀前端與後端目前的 README.md、環境變數範例與啟動設定。
需要在本機進行手動測試,請整理:
1. 需要先安裝的工具。
2. 資料庫、後端與前端的啟動順序。
3. 每個服務的網址與健康檢查方式。
4. 哪些設定要放在環境變數或 User Secrets。
這一輪只整理步驟,不要修改任何檔案,也不要顯示秘密內容。
這段 Prompt 有兩個用意。第一,要求 Codex 以現在的專案為準,不沿用舊指令。第二,明確提醒它不要把連線字串、密碼或 Token 印在回覆中。
如果想用 IDE 操作,也可以把工具一起說清楚:
需要使用 VS Code 啟動 Vue 前端,用 Rider 啟動 ASP.NET Core 後端。
請根據目前專案說明需要建立哪些啟動設定,以及如何確認兩邊都已成功啟動。
不要寫入密碼、Token 或私鑰。
Codex 整理的是操作說明,真正啟動時仍要看終端機與 IDE 的結果。畫面出現錯誤,不能因為回覆裡寫著「應該可以」就當作成功。
這個專案採前後端分離,三個部分要依序準備:
SQL Server 資料庫 → ASP.NET Core Web API → Vue 前端
順序不是硬性規定,但這樣比較容易判斷問題在哪裡。資料庫尚未就緒時,後端可能啟動失敗;後端沒有啟動時,前端雖然能顯示頁面,登入與資料查詢仍會失敗。
後端目前的 compose.yaml 已經安排 SQL Server 健康檢查、Migration 與 API 啟動順序。先進入後端專案,依 README.md 將 .env.example 複製為本機 .env,填入本機開發環境設定,再執行:
docker compose config
docker compose up --build
docker compose config 會展開環境變數,輸出中可能包含本機秘密,不要把完整內容貼到文章、Issue 或聊天室。啟動後要繼續確認 Container 狀態與 Log,不能只看到 Running 就認定 API 已經可以使用。
如果想在 Rider 下中斷點,仍要先準備可連線的 SQL Server。Rider 不會自動載入 Docker Compose 的 .env,因此連線字串應放進 .NET User Secrets,JWT 私鑰與 SMTP 設定則使用受保護的本機設定。不要把真實值寫進 appsettings.json 或提交到 Git。
在 Rider 選擇後端的 http 或 https launch profile 啟動後,可以依終端機顯示的 Port 檢查:
/health
/swagger
/openapi/v1.json
Health Endpoint 能回應、Swagger 或 OpenAPI 能開啟,才表示 API 至少已經接受連線。資料庫 Migration、登入與權限功能還要在後面的操作中繼續確認。
後端就緒後,進入前端專案:
npm install
cp .env.example .env.local
npm run dev
在 .env.local 將 VITE_API_BASE_URL 設成後端的 Origin。後端 README 的 Development 範例是 http://localhost:5080,但實際 Port 仍要以本機啟動輸出為準。Vite 啟動後,開啟終端機顯示的 Local URL,就能開始操作網站。
沒有清單的手動測試,很容易只測熟悉的順利流程。可先挑一條能串起主要功能的路徑:
每次發現問題,都應記下使用角色、測試資料、操作步驟、預期結果、實際結果與畫面截圖。只對 Codex 說「這裡怪怪的」,它仍然得猜問題在哪裡;把重現方式寫清楚,修改才比較容易一次對準。
專案詳情頁原本要讓管理者加入成員。畫面確實提供搜尋欄、Search 按鈕與使用者選單,但三個元件各做一半工作:使用者得先輸入關鍵字、按下搜尋,再到另一個選單挑人。

自動化測試只要能找到控制項、選到成員並完成新增,就可能判定通過。實際操作後才會發現,需求其實是「同一個下拉選單可以輸入關鍵字,也可以直接挑選結果」。這時 Prompt 不只要說畫面不好看,而要描述完整操作:
專案詳情頁的「加入成員」操作不符合預期。
目前行為:使用者要先在搜尋框輸入文字、按 Search,再到另一個下拉選單選人。
預期行為:改成一個可開啟、可輸入關鍵字篩選、可選取單一成員的下拉選單。
請先找出相關 Vue 元件、資料來源與既有測試,只修改這段操作流程。
保留 Project Role 選擇與 Add Member 按鈕;沒有符合結果時要顯示空狀態,載入時要避免重複送出。
完成後執行相關的元件測試與 Playwright 測試,並列出實際結果。
修改後,搜尋與選人回到同一個控制項。使用者不用在三個欄位之間來回找下一步,畫面也更接近 Day3 與 Day6 定義的操作情境。

使用 Admin 帳號打開使用者清單時,可能發現畫面允許直接調整目前登入帳號的系統角色與帳號狀態。

這個問題不只是按鈕放錯位置。假設系統只剩最後一位 Admin,卻讓該帳號降級或停用,系統可能從此沒有人能管理角色。就算後端已經擋下操作,前端仍不該把明知無法完成的選項當成一般功能;否則使用者只會在最後一步收到錯誤,還得猜是哪個步驟出了問題。
可以把 UI 與安全邊界一起交代:
手動測試發現,登入中的 Admin 可以在使用者清單看到修改目前登入帳號角色與帳號狀態的控制項。
請先核對 User Story、目前前後端實作與測試,再提出最小修改方案:
1. 前端對目前登入帳號隱藏或停用不允許的操作,並提供看得懂的原因。
2. 後端仍要強制保護最後一位啟用中的 Admin,不能只靠前端隱藏按鈕。
3. 補上「修改目前登入帳號」「停用最後一位 Admin」「調降最後一位 Admin」的測試。
如果現有規格互相衝突,先列出衝突,不要自行選一邊修改。
前端限制是路標,提醒使用者這條路不能走;後端授權才是門鎖。路標與門鎖都要有,不能因為畫面藏了按鈕,就假設 API 不會被直接呼叫。
問題修好後,不能只重按剛才失敗的那一步。加入成員的控制項改變後,還要確認成員清單、角色選擇、空結果與手機版沒有一起壞掉;Admin 保護調整後,也要確認一般的角色修改仍能正常完成。
至少要做三層確認:
如果手動測試找到了新的規則,也要回頭更新 User Story、Test Case 與自動化測試。否則這次靠人找到的問題,下次改版仍可能再出現。
Agent 回報完成、Build 成功、自動化測試全綠,都只是不同層次的證據。這些結果能指出程式是否能建置、已知規則是否通過,卻不能完整代表第一次使用的人能不能順利完成工作。
手動測試把測試者放回畫面前,實際確認每一步是否合理。這一輪發現的可搜尋下拉選單與 Admin 帳號管理問題,也說明了同一件事:程式「做得到」和功能「適合使用」之間,還需要一個人做最後判斷。
網站經過實際操作與修正後,下一篇會回頭更新 C4、API 契約與資料庫文件。設計圖不能只記錄最初想做什麼,也要反映最後真正做出了什麼。