完整程式碼可在 GitHub 專案中找到:Finetune-30-days-demo / day-14
在打造一個 AI 微調平台的過程中,我們需要不斷修改與優化系統。如果沒有測試保護,任何小小的改動都有可能破壞既有功能。
前半段的開發,我刻意沒有馬上補上單元測試,因為那時候架構還在大幅變動,邊寫邊測比較快。但隨著系統漸漸穩定,今天開始我決定把單元測試補齊,並且未來每個新功能都會更重視 TDD(Test-Driven Development),讓開發過程更有防護網。
傳統開發常見的模式是:先寫功能 → 執行 → 發現錯誤 → 臨時補測試。
TDD(Test-Driven Development)的想法是反過來:先寫測試,再實作功能。
這樣的好處是:
在這個過程中,我也讓 GPT 協助我快速產生測試案例,Cursor 則幫忙修改與補齊程式碼,讓測試能夠即時落地。這樣的 AI 協作方式,讓我能更快驗證平台的穩定性。
這次我為平台建立了 兩大類測試:
👉 確保核心功能「能跑得通」。
設計以下測試場景,避免系統在異常情況下崩潰:
👉 確保異常情況能被正確捕捉,而不是讓平台直接 crash。
我的做法是:
例如 API 測試中的一段簡化程式碼:
def test_task_status(client):
# 提交訓練任務
response = client.post("/train", json={"config_path": "config/test.yaml"})
task_id = response.json()["task_id"]
# 查詢任務狀態
status_response = client.get(f"/task/{task_id}")
assert status_response.status_code == 200
assert status_response.json()["status"] in ["PENDING", "STARTED", "SUCCESS"]
有了這層保護,我在修改 Celery 或 FastAPI 的邏輯時,就能確保 API 不會突然改壞。
透過這些測試,平台現在具備了基本的 穩定性:提交任務、查詢狀態、訓練流程都有測試保護;同時也涵蓋了數據錯誤與資源錯誤的模擬,避免平台在邊界情況下直接崩潰。這讓我能在後續重構與擴展功能時更有信心,不必擔心改壞舊有流程。
更重要的是,TDD 讓測試不再只是「找錯」,而是成為開發規格的一部分。對我而言,AI 協作的價值也在這裡:GPT 幫我快速生成測試範例,Cursor 實作細節,讓我可以專注在驗證設計是否正確。隨著這個測試基礎逐漸建立,平台才真正具備了「可持續優化」的能力。
📎 AI 協作記錄:今日開發指令
請幫我撰寫單元測試,新增以下檔案:
1. tests/test_api.py
- 測試 /train 任務提交是否成功回傳 task_id
- 測試 /task/{id} 回傳 PENDING / SUCCESS / FAILURE
- 測試無效 task_id 與 config 缺失的錯誤處理
2. tests/test_training.py
- 測試正常訓練流程,驗證步數與準確率
- 測試空資料集應該拋出錯誤
- 測試超長序列會正確截斷
- 測試記憶體不足錯誤會被攔截
要求:
- 使用 pytest
- 對外部依賴(Celery/Redis)使用 mock
- 測試命名清晰