T.C9 外接螢幕漏通知 — 訊息序列斷言與訂閱盲區
一條新流程上線後,外接第二螢幕停在上一個畫面——交易的另一方看不到當前狀態,主畫面卻一切正常、沒有任何錯誤浮現。漏通知的根因在機制,換誰開發都會再發生;驗證邊界則劃在出口——斷言送出的資料流與時序,裝置端的渲染交由裝置自己的系統驗證。
觀察
主裝置之外還有一面外接第二螢幕——面向交易另一方(例如顧客)的畫面,主畫面的狀態要同步過去。同步機制有兩種形態:
| 形態 | 例子 | 特性 |
|---|---|---|
| 訂閱驅動 | 本地清單變動 → 自動推送 | 資料流動就通知,不會漏 |
| 顯式呼叫 | 某流程完成後手動推送一次 | 每開一條新流程都要記得補一筆,容易漏 |
漏通知 bug 的成因:訂閱掛在「本地清單」的變動上,但有一條新流程走的是「遠端資料直接進入結帳」——資料不經過本地清單,訂閱永遠不觸發;而顯式呼叫沒人記得補。這是訂閱盲區:訂閱的資料源沒涵蓋所有會改變顯示內容的路徑。第二螢幕停在上一個畫面。
修復後補的驗證:所有送往第二螢幕的訊息都經過單一出口,測試注入一個錄音假件攔下每筆訊息(動作類型+內容),斷言序列——進結帳要推「畫面切換+品項清單」與「付款資訊」;完成時推「完成」;離開才推「清除」;且**「完成」必須先於「清除」**(順序顛倒時另一方看不到交易結果畫面,這是明文的時序約束)。
判讀
顯式呼叫是結構性風險點,可以被系統性審查。這份審查是一張可窮舉的清單:列出所有「會改變第二螢幕應顯示內容」的流程,逐一檢查它的資料走訂閱路徑、還是需要顯式推送。清單窮舉取代開發時的臨場記憶。
驗證邊界劃在「送出了什麼」。第二螢幕是另一個執行環境(甚至另一個引擎),它怎麼渲染不是這個測試套件能觸及的。正確的可測物是出口處的訊息流:內容、順序、時機。裝置端的渲染屬於另一個系統的職責。
序列斷言強於存在斷言。只斷言「有送完成訊息」抓不到「完成在清除之後」這種順序錯誤——而順序錯誤的使用者體驗傷害(看不到結果畫面)不亞於漏送。對有時序約束的訊息流,斷言用索引比較(完成的位置 < 清除的位置),而非個別存在性。
策略
- 收斂出口:所有外送訊息經過單一方法,測試才有唯一的攔截點。出口分散的程式先重構再談驗證。
- 錄音假件:以假件替換傳輸層,記錄(動作、內容)序列供斷言;不 mock 到業務層——業務到出口之間的編排正是要驗的對象。
- 時序約束寫成斷言:程式註解裡「A 必須在 B 之前」的每一句話,都應該有一條測試用索引比較把它鎖住。
- 長期方向:把顯式呼叫收編為訂閱。每多一條訂閱驅動的路徑,就少一個「記得補推送」的人為環節。訂閱化是消除這類 bug 的結構解。
下一步路由
- 這類流程測試的地基 → 語意級假後端與流程測試
- 序列斷言的設計品質 → 斷言品質三問
#testing #case-study #external-device #sequence-assertion #outbox