模擬器要重現條件而不只是跳數字
畫面上的值會變,還不足以驗證系統能處理異常。可重複的模擬案例需要固定初始狀態、輸入順序、時間條件與預期結果,讓今天修正後能用同一組條件再跑一次。每次隨機跳不同數字,失敗時很難知道差異來自程式還是測試本身。
先選模擬邊界:只是替換應用程式資料、模擬通訊伺服器,還是使用工程軟體模擬PLC掃描。不同邊界能驗證的能力不同;在畫面直接塞值可測顯示,卻不能證明實際協定解析、串列時序或實體接線正確。
本文提供平台無關的案例腳本設計,不宣稱某一套模擬器具有所有故障注入功能。實際工具、協定與版本必須確認;若只能模擬暫存器值,無法模擬封包破損,就把後者列為未覆蓋,而不是用錯值冒充通訊錯誤。
模擬器應只連測試網路與測試接收者,資料帶清楚的模擬來源識別。模擬產量、警報與命令不能流入正式報表或真實輸出。連線目標、帳號與資料路徑在每次啟動前可核對,避免依使用者上次留下的設定猜測。
先寫一條正常到異常再恢復的時間線
教學案例以模擬經過秒數為軸:零秒建立連線且初始化為未知;一秒提供值二十五與良好品質;三秒提供不良品質;五秒停止回應;八秒恢復連線但資料尚未確認;十秒提供新值二十六與良好品質。每個階段有獨立事件識別。
預期結果也逐步寫出:一秒顯示二十五,三秒不能再把二十五標為良好,停止回應後按系統約定逾時轉態,八秒不能只因連線恢復就宣告資料新鮮,十秒收到新證據才恢復。實際逾時發生時間取決於請求與逾時設定,不硬寫一定是五秒整。
此案例中的品質是模擬資料模型欄位;如果選用的協定沒有直接品質欄,應由模擬端錯誤行為與接收端品質判定配合驗證。不要把通訊層沒有的欄位塞進封包,然後宣稱測的是標準協定。
另寫純正常案例:初始化、穩定值、合法變化與正常停止。先確定正常路徑能通,再加入單一異常。一次同時斷線、改站號又改型別,雖可能讓畫面報錯,卻無法判斷哪個處理分支真的被驗證。
完成後應有案例識別、版本、初始狀態、步驟、時間或觸發條件、輸入及預期輸出。另存實際觀察時間與結果,腳本的計畫時間不是證明事件真的按時發生,仍需執行日誌核對。
固定狀態與時間才能重跑
每次案例開始清楚重設模擬器狀態、計數器、未完成請求與待送資料;被測系統也要有可確認的起始狀態。若上一次測試留下舊完成旗標,下一次可能一開始就顯示完成,與腳本正常與否無關。
使用相對時間或明確事件觸發,避免腳本寫死某年某月的電腦時間。測逾時時保留真實經過時間,測資料處理邏輯則可採可控制的模擬時鐘;兩者的證據不可混用,瞬間跳過十秒不能證明實際十秒逾時路徑表現相同。
若加入隨機雜訊,保存種子、產生器與版本,最好同時存下實際輸入序列。Python random提供設定種子與保存狀態的方法,但相同種子不代表任意程式版本、不同呼叫順序或多執行緒排程都得到相同測試。
把隨機序列產生與案例執行分開,可先產生固定資料檔,再按固定順序重播。如此即使程式因多讀一次狀態而改變呼叫次數,也不會偷偷改掉後面全部故障時點。探索性隨機測試找到問題後,縮成固定的可重現案例。
命令模擬要有狀態規則,不是收到任何寫入就回完成。例如接受請求後進入執行,再於指定條件完成;忙碌時的重複請求與非法參數各有回應。這樣才能驗證上位流程是否理解接受、執行與完成,而不是只看一個永遠成功的假設備。
用案例庫管理正常與故障覆蓋
案例至少涵蓋正常值、邊界、錯型別、延遲、無回應、恢復、重複事件與遲到資料,依工具能力取捨。每個案例列對應需求及故障注入層,缺乏工具支援的項目保留待驗證,不用一個籠統的異常案例包辦全部。
先驗證模擬器本身輸出符合腳本:檢查實際請求、回應、值與時間。若模擬器沒有真的停止回應,被測系統沒有逾時是合理的。測試結果要分成案例執行失敗、被測系統失敗與環境無效,避免把所有紅字都歸責給PLC或HMI。
失敗時保存最小可重現輸入、模擬器版本、被測版本、日誌與時間線,再重跑相同案例。只截最終錯誤畫面通常看不到前置狀態;若重跑通過,仍保留第一次失敗的條件與證據,不能把最後一次綠燈當成從未出錯。
驗收同一固定案例重跑多次,核對狀態轉移與輸出順序一致,時間差則按事先訂定容許範圍判斷。作業系統排程可能帶來時間抖動,不能要求所有毫秒完全相同;也不能把容許範圍放大到失去需求意義。
練習與常見問題
練習:寫一個三步案例,先提供有效計數十,再重送同一事件,最後提供新事件計數十一。預期唯一事件數只新增兩個,最終值十一。另把第三步改成舊事件遲到,預期不應把最新值倒退,具體規則依介面契約標示。
交付案例庫時同時附使用限制,例如未模擬實體電氣雜訊、未驗證PLC掃描與輸出硬體。模擬測試通過只涵蓋該邊界,後續工程軟體與現場驗證仍分開列出,不將不同層的證據互相替代。
問:隨機資料越多測試就越完整嗎?答:需要覆蓋需求與邊界,並能重現發現的問題。
問:固定種子就一定可重複嗎?答:還要固定版本、初始狀態與呼叫或輸入順序。
問:模擬器回成功等於設備會成功嗎?答:只證明模擬邊界內的行為,真實設備限制仍須驗證。
問:測試失敗可以先重跑到通過嗎?答:先保存失敗證據,重跑結果另外記錄,不能抹去不穩定問題。
參考:Python random:種子與產生器狀態保存,支援本文可重複輸入的觀念;整合案例為教學設計。