diff options
Diffstat (limited to 'src/cth_fail_fast.erl')
-rw-r--r-- | src/cth_fail_fast.erl | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/src/cth_fail_fast.erl b/src/cth_fail_fast.erl new file mode 100644 index 0000000..13b3557 --- /dev/null +++ b/src/cth_fail_fast.erl @@ -0,0 +1,118 @@ +-module(cth_fail_fast). + +%% Callbacks +-export([id/1]). +-export([init/2]). + +-export([pre_init_per_suite/3]). +-export([post_init_per_suite/4]). +-export([pre_end_per_suite/3]). +-export([post_end_per_suite/4]). + +-export([pre_init_per_group/3]). +-export([post_init_per_group/4]). +-export([pre_end_per_group/3]). +-export([post_end_per_group/4]). + +-export([pre_init_per_testcase/3]). +-export([post_end_per_testcase/4]). + +-export([on_tc_fail/3]). +-export([on_tc_skip/3, on_tc_skip/4]). + +-export([terminate/1]). + +%% We work by setting an 'abort' variable on each test case that fails +%% and then triggering the failure before starting the next test. This +%% ensures that all other hooks have run for the same event, and +%% simplifies error reporting. +-record(state, {abort=false}). + +%% @doc Return a unique id for this CTH. +id(_Opts) -> + {?MODULE, make_ref()}. + +%% @doc Always called before any other callback function. Use this to initiate +%% any common state. +init(_Id, _Opts) -> + {ok, #state{}}. + +%% @doc Called before init_per_suite is called. +pre_init_per_suite(_Suite,_Config,#state{abort=true}) -> + abort(); +pre_init_per_suite(_Suite,Config,State) -> + {Config, State}. + +%% @doc Called after init_per_suite. +post_init_per_suite(_Suite,_Config,Return,State) -> + {Return, State}. + +%% @doc Called before end_per_suite. +pre_end_per_suite(_Suite,_Config,#state{abort=true}) -> + abort(); +pre_end_per_suite(_Suite,Config,State) -> + {Config, State}. + +%% @doc Called after end_per_suite. +post_end_per_suite(_Suite,_Config,Return,State) -> + {Return, State}. + +%% @doc Called before each init_per_group. +pre_init_per_group(_Group,_Config,#state{abort=true}) -> + abort(); +pre_init_per_group(_Group,Config,State) -> + {Config, State}. + +%% @doc Called after each init_per_group. +post_init_per_group(_Group,_Config,Return, State) -> + {Return, State}. + +%% @doc Called after each end_per_group. +pre_end_per_group(_Group,_Config,#state{abort=true}) -> + abort(); +pre_end_per_group(_Group,Config,State) -> + {Config, State}. + +%% @doc Called after each end_per_group. +post_end_per_group(_Group,_Config,Return, State) -> + {Return, State}. + +%% @doc Called before each test case. +pre_init_per_testcase(_TC,_Config,#state{abort=true}) -> + abort(); +pre_init_per_testcase(_TC,Config,State) -> + {Config, State}. + +%% @doc Called after each test case. +post_end_per_testcase(_TC,_Config,ok,State) -> + {ok, State}; +post_end_per_testcase(_TC,_Config,Error,State) -> + {Error, State#state{abort=true}}. + +%% @doc Called after post_init_per_suite, post_end_per_suite, post_init_per_group, +%% post_end_per_group and post_end_per_testcase if the suite, group or test case failed. +on_tc_fail(_TC, _Reason, State) -> + State. + +%% @doc Called when a test case is skipped by either user action +%% or due to an init function failing. (>= 19.3) +on_tc_skip(_Suite, _TC, {tc_auto_skip, _}, State) -> + State#state{abort=true}; +on_tc_skip(_Suite, _TC, _Reason, State) -> + State. + +%% @doc Called when a test case is skipped by either user action +%% or due to an init function failing. (Pre-19.3) +on_tc_skip(_TC, {tc_auto_skip, _}, State) -> + State#state{abort=true}; +on_tc_skip(_TC, _Reason, State) -> + State. + +%% @doc Called when the scope of the CTH is done +terminate(#state{}) -> + ok. + +%%% Helpers +abort() -> + io:format(user, "Detected test failure. Aborting~n", []), + halt(1). |