ISA後端指令
TimeControl
控制測試中的 Mock 時間
TimeControl 設定框架提供的 MockTime 介面回傳的時間,並控制所有使用 now 關鍵字的時間符號與 CAS 時間約束。開發者需在應用程式中注入 MockTime 介面取代系統時鐘,以確保時間相依測試的穩定性。
基本用法
Given 現在時間為 "2026-01-27T10:00:00"這段指令會:
- 將 MockTime 介面的回傳時間設為
2026-01-27T10:00:00 - 所有使用
now的時間符號(如@time("now")、@date("now"))和 CAS 時間約束(如&sameTime("now"))都會以此時間為基準
為什麼需要控制時間?
沒有 TimeControl 時,測試依賴系統時鐘,不同時間執行會產生不同結果:
# ❌ 沒有 TimeControl:只有在特定時間執行才會通過
Then 新增待辦事項(201)回應, with table:
| createdAt |
| &sameTime("2026-02-12T10:00:00") |
# ✅ 有 TimeControl:無論何時執行都通過
Given 現在時間為 "2026-02-01T10:00:00"
Then 新增待辦事項(201)回應, with table:
| createdAt |
| &sameTime("2026-02-01T10:00:00") |支援的時間格式
| 格式 | 範例 |
|---|---|
| 純日期 | 2025-12-25(預設 00:00:00) |
| ISO 無時區 | 2025-11-04T08:00:00(使用系統時區) |
| ISO 含時區 | 2025-12-25T14:30:00+08:00 |
| ISO UTC | 2025-12-25T06:30:00Z |
| 時間符號 | @time("2025-12-25T14:30:00")(參見 TIME-System) |
影響範圍
TimeControl 設定的時間會影響所有使用 now 關鍵字的表達式:
時間符號
| 符號 | 說明 |
|---|---|
@time("now") | 回傳 MockTime 的當前時間 |
@time("now+1d") | 基於 MockTime 當前時間的相對計算 |
@date("now") | 回傳 MockTime 的當前日期 |
@localtime("now") | 回傳 MockTime 的當前時間(僅時間) |
CAS 時間約束
| 約束 | 說明 |
|---|---|
&sameTime("now") | 驗證值等於 MockTime 的當前時間 |
&before("now") | 驗證值早於 MockTime 的當前時間 |
&after("now") | 驗證值晚於 MockTime 的當前時間 |
時間符號與 CAS 時間約束可用於任何指令的 DataTable 欄位中。
錯誤處理
執行階段
| 錯誤 | 說明 |
|---|---|
| 缺少時間參數 | 時間表達式為空 |
| 無法解析 | 時間格式不符合支援的格式 |
完整範例
Feature: 待辦事項時間控制
Background:
Given 現在時間為 "2026-01-27T10:00:00"
Given 準備一個使用者, with table:
| >Alice.id | name | email | status |
| <userId | Alice | alice@example.com | ACTIVE |
Example: 新增後推進時間再更新
# 1. 新增待辦事項(createdAt = 2026-01-27T10:00:00)
When (UID="$Alice.id") 新增待辦事項, call table:
| >todo1.id | title |
| <todoId | 買牛奶 |
Then 新增待辦事項(201)回應, with table:
| todoId | createdAt |
| $todo1.id | &sameTime("2026-01-27T10:00:00") |
# 2. 推進時間 1 天
Given 現在時間為 "@time("now+1d")"
# 3. 更新待辦事項(updatedAt = 2026-01-28T10:00:00)
When (UID="$Alice.id") 更新待辦事項, call table:
| P:todoId | title |
| $todo1.id | 買豆漿 |
Then 更新待辦事項(200)回應, with table:
| todoId | updatedAt |
| $todo1.id | &sameTime("2026-01-28T10:00:00") |