檢視原始碼 ct_hooks 行為 (common_test v1.27.5)
Common Test 之上的回呼介面。
Common Test Hook (CTH) 框架允許透過在所有測試套件呼叫前後的回呼來擴展 Common Test
的預設行為。它適用於想要抽象出多個測試套件通用行為的 Common Test
進階使用者。
簡而言之,CTH 允許您:
- 在每次套件配置呼叫之前操作執行階段配置。
- 操作所有套件配置呼叫的回傳值,並擴展測試本身的結果。
以下章節描述了 Common Test
在測試執行期間呼叫的強制性和可選 CTH 函式。如需更多詳細資訊,請參閱使用者指南中的 Common Test Hooks 章節。
有關如何將 CTH 新增到您的套件,請參閱使用者指南中的 安裝 CTH 章節。
注意
如需 CTH 的最小範例,請參閱使用者指南中的 CTH 範例 章節。
摘要
回呼:回呼函式
Id
唯一識別一個 CTH 實例。如果兩個 CTH 回傳相同的 Id
,則會忽略第二個 CTH,並且後續對 CTH 的呼叫只會給第一個實例。如需詳細資訊,請參閱使用者指南中的 安裝 CTH 章節。
此函式總是在任何其他回呼函式之前呼叫。使用它來初始化任何通用狀態。它將為此 CTH 回傳一個狀態。
只要測試案例(或配置函式)失敗,就會呼叫此函式。它會在失敗的測試案例呼叫 post 函式之後呼叫。
只要測試案例(或配置函式)被跳過,就會呼叫此函式。它會在跳過的測試案例呼叫 post 函式之後呼叫。
此函式會在 all/0
之後呼叫。它用於修改要執行的測試案例和測試群組的集合,例如新增或移除測試案例和群組、變更群組屬性,甚至跳過套件中的所有測試。
如果 end_per_group
存在,則會在之後呼叫此函式。它的行為與 post_init_per_suite
相同,但用於函式 end_per_group。
如果 end_per_suite
存在,則會在之後呼叫此函式。它的行為與 post_init_per_suite
相同,但用於函式 end_per_suite
。
如果 end_per_testcase
存在,則會在之後呼叫此函式。它的行為與 post_end_per_suite
相同,但用於函式 end_per_testcase
。
此函式會在 groups/0
之後呼叫。它用於修改測試群組定義,例如新增或移除群組或變更群組屬性。
如果 init_per_group
存在,則會在之後呼叫此函式。它的行為與 post_init_per_suite
相同,但用於函式 init_per_group
。
如果 init_per_suite
存在,則會在之後呼叫此函式。它通常包含額外的檢查,以確保所有正確的相依性都已正確啟動。
如果 init_per_testcase
存在,則會在之後呼叫此函式。它的行為與 post_init_per_suite
相同,但用於函式 init_per_testcase
。
如果 end_per_group
存在,則會在之前呼叫此函式。它的行為與 pre_init_per_suite
相同,但用於函式 end_per_group
。
如果 end_per_suite
存在,則會在之前呼叫此函式。它的行為與 pre_init_per_suite
相同,但用於函式 end_per_suite
。
如果 end_per_testcase
存在,則會在之前呼叫此函式。它的行為與 pre_end_per_suite
相同,但用於函式 end_per_testcase
。
如果 init_per_group
存在,則會在之前呼叫此函式。它的行為與 pre_init_per_suite
相同,但用於函式 init_per_group
。
如果 init_per_suite
存在,則會在之前呼叫此函式。它通常包含必須在呼叫 init_per_suite
之前完成的初始化/記錄。如果回傳 {skip,Reason}
或 {fail,Reason}
,則會跳過 init_per_suite
和套件的所有測試案例,並且在套件的總覽日誌中列印 Reason
。
如果 init_per_testcase
存在,則會在之前呼叫此函式。它的行為與 pre_init_per_suite
相同,但用於函式 init_per_testcase
。
此函式會在 CTH 範圍 的末尾呼叫。回傳的項會被忽略。
回呼:回呼函式
Id
唯一識別一個 CTH 實例。如果兩個 CTH 回傳相同的 Id
,則會忽略第二個 CTH,並且後續對 CTH 的呼叫只會給第一個實例。如需詳細資訊,請參閱使用者指南中的 安裝 CTH 章節。
此函式不應有任何副作用,因為 Common Test
可以多次呼叫它。
如果未實作,則 CTH 的行為就像此函式回傳對 make_ref/0
的呼叫一樣。
-callback init(Id, Opts) -> {ok, State} | {ok, State, Priority} when Id :: reference() | term(), Opts :: term(), State :: term(), Priority :: integer().
此函式總是在任何其他回呼函式之前呼叫。使用它來初始化任何通用狀態。它將為此 CTH 回傳一個狀態。
Id
要么是 ct_hooks:id/1
的回傳值,要么是一個 reference
(使用 ERTS 中的 erlang:make_ref/0
建立),如果未實作 ct_hooks:id/1
。
Priority
是此 Hook 的相對優先順序。具有較低優先順序的 Hook 會先執行。如果未指定優先順序,則會將其設定為 0
。
如需關於 Hook 執行順序的詳細資訊,請參閱使用者指南中的 CTH 執行順序 章節。
如需關於何時呼叫 init
的詳細資訊,請參閱使用者指南中的 CTH 範圍 章節。
-callback on_tc_fail(SuiteName, TestName, Reason, CTHState) -> NewCTHState when SuiteName :: atom(), TestName :: init_per_suite | end_per_suite | {init_per_group, GroupName} | {end_per_group, GroupName} | {FuncName, GroupName} | FuncName, FuncName :: atom(), GroupName :: atom(), Reason :: term(), CTHState :: term(), NewCTHState :: term().
只要測試案例(或配置函式)失敗,就會呼叫此函式。它會在失敗的測試案例呼叫 post 函式之後呼叫。
也就是說:
- 如果
init_per_suite
失敗,則會在post_init_per_suite
之後呼叫此函式。 - 如果測試案例失敗,則會在
post_end_per_testcase
之後呼叫此函式。
如果失敗的測試案例屬於測試案例群組,則第二個引數是一個元組 {FuncName,GroupName}
,否則只有函式名稱。
Reason
附帶的資料格式與事件 tc_done
中的 FailReason
相同。如需詳細資訊,請參閱使用者指南中的 事件處理 章節。
如果未匯出 Module:on_tc_fail/4
,common_test 將嘗試呼叫 Module:on_tc_fail(TestName, Reason, CTHState)
。這是為了向後相容性。
-callback on_tc_skip(SuiteName, TestName, Reason, CTHState) -> NewCTHState when SuiteName :: atom(), TestName :: init_per_suite | end_per_suite | {init_per_group, GroupName} | {end_per_group, GroupName} | {FuncName, GroupName} | FuncName, FuncName :: atom(), GroupName :: atom(), Reason :: {tc_auto_skip | tc_user_skip, term()}, CTHState :: term(), NewCTHState :: term().
只要測試案例(或配置函式)被跳過,就會呼叫此函式。它會在跳過的測試案例呼叫 post 函式之後呼叫。
也就是說:
- 如果跳過
init_per_group
,則會在post_init_per_group
之後呼叫此函式。 - 如果跳過測試案例,則會在
post_end_per_testcase
之後呼叫此函式。
如果跳過的測試案例屬於測試案例群組,則第二個引數是一個元組 {FuncName,GroupName}
,否則只有函式名稱。
Reason
附帶的資料格式與事件 tc_auto_skip
和 tc_user_skip
相同。如需詳細資訊,請參閱使用者指南中的 事件處理 章節。
如果未匯出 Module:on_tc_skip/4
,common_test 將嘗試呼叫 Module:on_tc_skip(TestName, Reason, CTHState)
。這是為了向後相容性。
-callback post_all(SuiteName, Return, GroupDefs) -> NewReturn when SuiteName :: atom(), Return :: Tests | {skip, Reason}, NewReturn :: Tests | {skip, Reason}, Tests :: [TestCase | {testcase, TestCase, TCRepeatProps} | {group, GroupName} | {group, GroupName, Properties} | {group, GroupName, Properties, SubGroups}], TestCase :: atom(), TCRepeatProps :: [{repeat, N} | {repeat_until_ok, N} | {repeat_until_fail, N}], GroupName :: atom(), Properties :: GroupProperties | default, SubGroups :: [{GroupName, Properties} | {GroupName, Properties, SubGroups}], Shuffle :: shuffle | {shuffle, Seed}, Seed :: {integer(), integer(), integer()}, GroupRepeatType :: repeat | repeat_until_all_ok | repeat_until_all_fail | repeat_until_any_ok | repeat_until_any_fail, N :: integer() | forever, GroupDefs :: [Group], Group :: {GroupName, GroupProperties, GroupsAndTestCases}, GroupProperties :: [parallel | sequence | Shuffle | {GroupRepeatType, N}], GroupsAndTestCases :: [Group | {group, GroupName} | TestCase], Reason :: term().
此函式會在 all/0
之後呼叫。它用於修改要執行的測試案例和測試群組的集合,例如新增或移除測試案例和群組、變更群組屬性,甚至跳過套件中的所有測試。
Return
是 all/0
回傳的內容,也就是要執行的測試案例和群組的列表,或一個元組 {skip,Reason}
。
GroupDefs
是 groups/0
或 post_groups/2
hook 回傳的內容,也就是群組定義的列表。
NewReturn
是 Return
可能修改的版本。
只有在 init_per_suite
執行之前加入 CTH 時,才會呼叫此函式。詳情請參閱使用者指南中的 CTH 範圍 章節。
請注意,對於透過 suite/0
函式安裝的 CTH,post_all/2
會在 init/2
hook 函式之前呼叫。但是,對於透過 CT 啟動旗標安裝的 CTH,會先呼叫 init/2
函式。
注意
在每次測試執行之前,Common Test 會執行模擬測試,以便計算測試套件、群組和測試案例,以用於記錄。這會導致
post_all/3
hook 函式總是會被呼叫兩次。因此,最好避免在此回呼中產生副作用。
-callback post_end_per_group(SuiteName, GroupName, Config, Return, CTHState) -> Result when SuiteName :: atom(), GroupName :: atom(), Config :: [{Key, Value}], Return :: Config | SkipOrFail | term(), NewReturn :: Config | SkipOrFail | term(), SkipOrFail :: {fail, Reason} | {skip, Reason}, CTHState :: term(), NewCTHState :: term(), Result :: {NewReturn, NewCTHState}, Key :: atom(), Value :: term(), Reason :: term().
如果 end_per_group
存在,則會在之後呼叫此函式。它的行為與 post_init_per_suite
相同,但用於函式 end_per_group。
如果沒有匯出 Module:post_end_per_group/5
,common_test 會嘗試改為呼叫 Module:post_end_per_group(GroupName, Config, Return, CTHState)
。這是為了向後相容性。
-callback post_end_per_suite(SuiteName, Config, Return, CTHState) -> Result when SuiteName :: atom(), Config :: [{Key, Value}], Return :: Config | SkipOrFail | term(), NewReturn :: Config | SkipOrFail | term(), SkipOrFail :: {fail, Reason} | {skip, Reason}, CTHState :: term(), NewCTHState :: term(), Result :: {NewReturn, NewCTHState}, Key :: atom(), Value :: term(), Reason :: term().
如果 end_per_suite
存在,則會在之後呼叫此函式。它的行為與 post_init_per_suite
相同,但用於函式 end_per_suite
。
post_end_per_testcase(SuiteName, TestcaseName, Config, Return, CTHState)
檢視原始碼 (選用) (自 OTP 19.3 起)-callback post_end_per_testcase(SuiteName, TestcaseName, Config, Return, CTHState) -> Result when SuiteName :: atom(), TestcaseName :: atom(), Config :: [{Key, Value}], Return :: Config | SkipOrFail | term(), NewReturn :: Config | SkipOrFail | term(), SkipOrFail :: {fail, Reason} | {skip, Reason}, CTHState :: term(), NewCTHState :: term(), Result :: {NewReturn, NewCTHState}, Key :: atom(), Value :: term(), Reason :: term().
如果 end_per_testcase
存在,則會在之後呼叫此函式。它的行為與 post_end_per_suite
相同,但用於函式 end_per_testcase
。
如果沒有匯出 Module:post_end_per_testcase/5
,common_test 會嘗試改為呼叫 Module:post_end_per_testcase(TestcaseName, Config, Return, CTHState)
。這是為了向後相容性。
-callback post_groups(SuiteName, GroupDefs) -> NewGroupDefs when SuiteName :: atom(), GroupDefs :: [Group], NewGroupDefs :: [Group], Group :: {GroupName, Properties, GroupsAndTestCases}, GroupName :: atom(), Properties :: [parallel | sequence | Shuffle | {GroupRepeatType, N}], GroupsAndTestCases :: [Group | {group, GroupName} | TestCase | {testcase, TestCase, TCRepeatProps}], TestCase :: atom(), TCRepeatProps :: [{repeat, N} | {repeat_until_ok, N} | {repeat_until_fail, N}], Shuffle :: shuffle | {shuffle, Seed}, Seed :: {integer(), integer(), integer()}, GroupRepeatType :: repeat | repeat_until_all_ok | repeat_until_all_fail | repeat_until_any_ok | repeat_until_any_fail, N :: integer() | forever.
此函式會在 groups/0
之後呼叫。它用於修改測試群組定義,例如新增或移除群組或變更群組屬性。
GroupDefs
是 groups/0
回傳的內容,也就是群組定義的列表。
NewGroupDefs
是此列表可能經過修改的版本。
只有在 init_per_suite
執行之前加入 CTH 時,才會呼叫此函式。詳情請參閱使用者指南中的 CTH 範圍 章節。
請注意,對於透過 suite/0
函式安裝的 CTH,post_groups/2
會在 init/2
hook 函式之前呼叫。但是,對於透過 CT 啟動旗標安裝的 CTH,會先呼叫 init/2
函式。
注意
在每次測試執行之前,Common Test 會執行模擬測試,以便計算測試套件、群組和測試案例,以用於記錄。這會導致
post_groups/2
hook 函式總是會被呼叫兩次。因此,最好避免在此回呼中產生副作用。
post_init_per_group(SuiteName, GroupName, Config, Return, CTHState)
檢視原始碼 (選用) (自 OTP 19.3 起)-callback post_init_per_group(SuiteName, GroupName, Config, Return, CTHState) -> Result when SuiteName :: atom(), GroupName :: atom(), Config :: [{Key, Value}], Return :: Config | SkipOrFail | term(), NewReturn :: Config | SkipOrFail | term(), SkipOrFail :: {fail, Reason} | {skip, Reason}, CTHState :: term(), NewCTHState :: term(), Result :: {NewReturn, NewCTHState}, Key :: atom(), Value :: term(), Reason :: term().
如果 init_per_group
存在,則會在之後呼叫此函式。它的行為與 post_init_per_suite
相同,但用於函式 init_per_group
。
如果沒有匯出 Module:post_init_per_group/5
,common_test 會嘗試改為呼叫 Module:post_init_per_group(GroupName, Config, Return, CTHState)
。這是為了向後相容性。
-callback post_init_per_suite(SuiteName, Config, Return, CTHState) -> Result when SuiteName :: atom(), Config :: [{Key, Value}], Return :: Config | SkipOrFail | term(), NewReturn :: Config | SkipOrFail | term(), SkipOrFail :: {fail, Reason} | {skip, Reason} | term(), CTHState :: term(), NewCTHState :: term(), Result :: {NewReturn, NewCTHState}, Key :: atom(), Value :: term(), Reason :: term().
如果 init_per_suite
存在,則會在之後呼叫此函式。它通常包含額外的檢查,以確保所有正確的相依性都已正確啟動。
Return
是 init_per_suite
回傳的內容,也就是 {fail,Reason}
、{skip,Reason}
、Config
列表,或描述 init_per_suite
如何失敗的詞彙。
NewReturn
是 init_per_suite
可能經過修改的回傳值。若要從 init_per_suite
的失敗中恢復,請回傳移除 tc_status
元素的 ConfigList
。如需更多詳細資訊,請參閱使用者指南中「操作測試」章節中的 Post Hooks。
CTHState
是 CTH 目前的內部狀態。
只有在 init_per_suite
之前或之中加入 CTH 時,才會呼叫此函式。詳情請參閱使用者指南中的 CTH 範圍 章節。
post_init_per_testcase(SuiteName, TestcaseName, Config, Return, CTHState)
檢視原始碼 (選用) (自 OTP 19.3 起)-callback post_init_per_testcase(SuiteName, TestcaseName, Config, Return, CTHState) -> Result when SuiteName :: atom(), TestcaseName :: atom(), Config :: [{Key, Value}], Return :: Config | SkipOrFail | term(), NewReturn :: Config | SkipOrFail | term(), SkipOrFail :: {fail, Reason} | {skip, Reason}, CTHState :: term(), NewCTHState :: term(), Result :: {NewReturn, NewCTHState}, Key :: atom(), Value :: term(), Reason :: term().
如果 init_per_testcase
存在,則會在之後呼叫此函式。它的行為與 post_init_per_suite
相同,但用於函式 init_per_testcase
。
如果沒有匯出 Module:post_init_per_testcase/5
,common_test 會嘗試改為呼叫 Module:post_init_per_testcase(TestcaseName, Config, Return, CTHState)
。這是為了向後相容性。
-callback pre_end_per_group(SuiteName, GroupName, EndData, CTHState) -> Result when SuiteName :: atom(), GroupName :: atom(), EndData :: Config | SkipOrFail, Config :: [{Key, Value}], NewConfig :: [{Key, Value}], CTHState :: term(), NewCTHState :: term(), Result :: {NewConfig | SkipOrFail, NewCTHState}, SkipOrFail :: {fail, Reason} | {skip, Reason}, Key :: atom(), Value :: term(), Reason :: term().
如果 end_per_group
存在,則會在之前呼叫此函式。它的行為與 pre_init_per_suite
相同,但用於函式 end_per_group
。
如果沒有匯出 Module:pre_end_per_group/4
,common_test 會嘗試改為呼叫 Module:pre_end_per_group(GroupName, EndData, CTHState)
。這是為了向後相容性。
-callback pre_end_per_suite(SuiteName, EndData, CTHState) -> Result when SuiteName :: atom(), EndData :: Config | SkipOrFail, Config :: [{Key, Value}], NewConfig :: [{Key, Value}], CTHState :: term(), NewCTHState :: term(), Result :: {NewConfig | SkipOrFail, NewCTHState}, SkipOrFail :: {fail, Reason} | {skip, Reason}, Key :: atom(), Value :: term(), Reason :: term().
如果 end_per_suite
存在,則會在之前呼叫此函式。它的行為與 pre_init_per_suite
相同,但用於函式 end_per_suite
。
-callback pre_end_per_testcase(SuiteName, TestcaseName, EndData, CTHState) -> Result when SuiteName :: atom(), TestcaseName :: atom(), EndData :: Config, Config :: [{Key, Value}], NewConfig :: [{Key, Value}], CTHState :: term(), NewCTHState :: term(), Result :: {NewConfig, NewCTHState}, Key :: atom(), Value :: term().
如果 end_per_testcase
存在,則會在之前呼叫此函式。它的行為與 pre_end_per_suite
相同,但用於函式 end_per_testcase
。
此函式無法透過回傳 skip 或 fail 元組來變更測試案例的結果,但它可以在 Config
中插入項目,這些項目可以在 end_per_testcase/2
或 post_end_per_testcase/5
中讀取。
如果沒有匯出 Module:pre_end_per_testcase/4
,common_test 會嘗試改為呼叫 Module:pre_end_per_testcase(TestcaseName, EndData, CTHState)
。這是為了向後相容性。
-callback pre_init_per_group(SuiteName, GroupName, InitData, CTHState) -> Result when SuiteName :: atom(), GroupName :: atom(), InitData :: Config | SkipOrFail, Config :: [{Key, Value}], NewConfig :: [{Key, Value}], CTHState :: term(), NewCTHState :: term(), Result :: {NewConfig | SkipOrFail, NewCTHState}, SkipOrFail :: {fail, Reason} | {skip, Reason}, Key :: atom(), Value :: term(), Reason :: term().
如果 init_per_group
存在,則會在之前呼叫此函式。它的行為與 pre_init_per_suite
相同,但用於函式 init_per_group
。
如果沒有匯出 Module:pre_init_per_group/4
,common_test 會嘗試改為呼叫 Module:pre_init_per_group(GroupName, InitData, CTHState)
。這是為了向後相容性。
-callback pre_init_per_suite(SuiteName, InitData, CTHState) -> Result when SuiteName :: atom(), InitData :: Config | SkipOrFail, Config :: [{Key, Value}], NewConfig :: [{Key, Value}], CTHState :: term(), NewCTHState :: term(), Result :: {Return, NewCTHState}, Return :: NewConfig | SkipOrFail, SkipOrFail :: {fail, Reason} | {skip, Reason}, Key :: atom(), Value :: term(), Reason :: term().
如果 init_per_suite
存在,則會在之前呼叫此函式。它通常包含必須在呼叫 init_per_suite
之前完成的初始化/記錄。如果回傳 {skip,Reason}
或 {fail,Reason}
,則會跳過 init_per_suite
和套件的所有測試案例,並且在套件的總覽日誌中列印 Reason
。
SuiteName
是要執行的套件名稱。
InitData
是測試套件的原始組態列表,或是如果先前的 CTH 回傳此值,則為 SkipOrFail
元組。
CTHState
是 CTH 目前的內部狀態。
Return
是 init_per_suite
函式的結果。如果它是 {skip,Reason}
或 {fail,Reason}
,則永遠不會呼叫 init_per_suite
,而是會將初始化視為已跳過或失敗。如果回傳 NewConfig
列表,則會使用該 NewConfig
列表呼叫 init_per_suite
。如需更多詳細資訊,請參閱使用者指南中 Pre Hooks 章節。
只有在 init_per_suite is run
之前加入 CTH 時,才會呼叫此函式。詳情請參閱使用者指南中的 CTH 範圍 章節。
-callback pre_init_per_testcase(SuiteName, TestcaseName, InitData, CTHState) -> Result when SuiteName :: atom(), TestcaseName :: atom(), InitData :: Config | SkipOrFail, Config :: [{Key, Value}], NewConfig :: [{Key, Value}], CTHState :: term(), NewCTHState :: term(), Result :: {NewConfig | SkipOrFail, NewCTHState}, SkipOrFail :: {fail, Reason} | {skip, Reason}, Key :: atom(), Value :: term(), Reason :: term().
如果 init_per_testcase
存在,則會在之前呼叫此函式。它的行為與 pre_init_per_suite
相同,但用於函式 init_per_testcase
。
如果沒有匯出 Module:pre_init_per_testcase/4
,common_test 會嘗試改為呼叫 Module:pre_init_per_testcase(TestcaseName, InitData, CTHState)
。這是為了向後相容性。
目前無法在此處加入 CTH。該功能可能會在稍後的版本中新增,但現在會破壞向後相容性。
此函式會在 CTH 範圍 的末尾呼叫。回傳的項會被忽略。