iT邦幫忙

2026 iThome 鐵人賽

DAY 17
0
Software Development

同一套 Laravel 系統,測試怎麼寫才不會說謊系列 第 17

Day 17:VCR 測試法總覽——23 個 cassette 檔案怎麼分類組織

  • 分享至 

  • xImage
  •  

前言

「錄一次真實流量當測試資料,聽起來很方便,但錄下來的檔案越積越多,怎麼避免亂成一團?」

昨天講了兩支測試替身怎麼共用同一份錄製資料,今天要把鏡頭拉遠一點,看整個「錄影帶」機制的全貌——這個系統目前累積了 23 個 YAML 格式的 cassette 檔案,怎麼分類、怎麼命名,才不會變成一堆誰也搞不清楚錄的是什麼的檔案。

今日目標

  • 認識 VCR(Video Cassette Recorder)測試法的基本概念:錄一次真實互動,之後重播
  • 看這個系統的 23 個 cassette 檔案怎麼依用途分類
  • 理解檔名設計本身也是一種索引機制
  • 建立判斷力:什麼情境適合用 VCR 錄製重播,什麼情境不適合

VCR 測試法在做什麼

VCR 測試法的核心概念很直覺:第一次執行測試時,讓程式碼真的去打外部服務,把完整的請求跟回應內容錄下來存成檔案;之後每次執行測試,不再真的打外部服務,而是重播錄下來的內容。好處是測試可以在完全沒有網路、外部系統離線的情況下穩定執行,而且執行速度不受外部服務的回應時間影響;代價是如果外部系統的行為真的改變了,重播的內容不會自動更新,需要重新錄製。

這個系統的 cassette 怎麼分類

tests/fixtures/vcr/ 目錄底下的 23 個 YAML 檔案,大致分成三類:

對應各種 Job 的完整流程錄影:每一支跟外部系統同步資料的排程 Job,各自有一份對應的 cassette,記錄那支 Job 完整跑一輪需要打的所有外部請求跟回應。值得注意的是,有幾份檔名裡直接編進了分頁參數(例如某份檔名標注了特定的分頁位移量),代表這支 Job 在不同分頁位置的行為,被視為需要各自獨立驗證的情境,不是隨便錄一次分頁就當作代表全部。

外部 SOAP 服務各自的查詢方法:對應外部校務系統提供的各種查詢介面(帳號查詢、身份資訊查詢等),每種查詢方法各自有獨立的 cassette。

登入跟爬蟲相關的錄影:對應單一登入流程跟外部網頁爬取的錄製資料。

檔名本身是一種索引設計

只用功能名稱命名,看不出細節

sync_staffs.yaml

如果同一支 Job 因為分頁參數不同,行為會不一樣,但所有情境都塞進同一個檔名,之後要嘛只錄了其中一種分頁情境當代表(容易漏掉其他分頁位置可能出現的邊界問題),要嘛把好幾種情境的錄影硬塞進同一個檔案,難以分辨哪一段對應哪一種情況。

把關鍵參數編進檔名

sync_staffs_offset_10800.yaml

檔名直接告訴你這份錄影對應的是分頁位移量在 10800 這個位置的行為。之後如果要新增一份測試分頁邊界情況的錄影,可以直接命名成對應的位移量,讀檔名就知道每一份錄影分別驗證的是哪一種分頁情境,不需要打開檔案內容才搞清楚。

VCR 不是所有情境都適用

VCR 測試法適合的場景,是外部系統的行為相對穩定、你只是需要「不要每次測試都真的打外部服務」;如果外部系統的回應內容經常變動、或者你要驗證的是「當外部系統回應格式跑掉時我這邊會怎麼反應」這種邊界情況,錄一次真實流量不一定能涵蓋到,這時候手動建構特定格式的假資料(就像 Day 15 講的 dataset 手法)反而更直接。VCR 適合驗證「正常流程走得通」,不太適合驗證「各種異常情況有沒有被正確處理」。

今日思考題

如果你的專案也有跟外部系統整合的測試替身,你的假資料檔案命名方式,能不能讓下一個接手的人一眼看出每份檔案對應的是哪一種情境?如果不能,光靠檔名多加幾個關鍵參數,會不會就足夠了?

今日重點回顧

  • VCR 測試法錄一次真實互動、之後重播,讓測試不需要每次都真的打外部服務
  • 這個系統的 23 個 cassette 依用途分成 Job 流程、SOAP 查詢方法、登入/爬蟲三類
  • 把關鍵參數(例如分頁位移量)編進檔名,本身就是一種索引設計
  • VCR 適合驗證「正常流程走得通」,不適合驗證各種異常回應情況

明日預告

明天要具體看一支 SOAP Client 的單元測試,完整走一次「注入 Fake、驗證回傳結構」這個流程長什麼樣。


上一篇
Day 16:Fake 測試替身設計——同一份錄影帶,兩支不同協定的 Fake 各自挑自己看得懂的部分播放
下一篇
Day 18:SOAP Client 測試——不真的打外部系統也能驗證邏輯
系列文
同一套 Laravel 系統,測試怎麼寫才不會說謊19
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言