@@ -166,6 +166,8 @@ will be run.
166166 Can be used to load packages or set up the environment. Must be a `:block` expression.
167167- `test_end_expr::Expr`: an expression that will be run after each testitem is run.
168168 Can be used to verify that global state is unchanged after running a test. Must be a `:block` expression.
169+ The `test_end_expr` is evaluated whether a testitem passes, fails, or errors. If the
170+ `testsetup` fails, then the `test_end_expr` is not run.
169171- `gc_between_testitems::Bool`: If `true`, a full garbage collection (GC) will be run after each test item is run.
170172 Defaults to `nworkers > 1`, i.e. `true` when running with multiple worker processes, since multiple worker processes
171173 cannot coordinate to trigger Julia's GC, and it should not be necessary to invoke the GC directly if running without
@@ -955,11 +957,17 @@ end
955957# when `runtestitem` called directly or `@testitem` called outside of `runtests`.
956958function runtestitem (
957959 ti:: TestItem , ctx:: TestContext ;
958- test_end_expr:: Expr = Expr ( :block ) , logs:: Symbol = :eager , verbose_results:: Bool = true , finish_test:: Bool = true ,
960+ test_end_expr:: Union{Nothing, Expr} = nothing , logs:: Symbol = :eager , verbose_results:: Bool = true , finish_test:: Bool = true ,
959961)
960962 if should_skip (ti):: Bool
961963 return skiptestitem (ti, ctx; verbose_results)
962964 end
965+ if test_end_expr === nothing
966+ has_test_end_expr = false
967+ test_end_expr = Expr (:block )
968+ else
969+ has_test_end_expr = true
970+ end
963971 name = ti. name
964972 log_testitem_start (ti, ctx. ntestitems)
965973 ts = DefaultTestSet (name; verbose= verbose_results)
@@ -1024,8 +1032,13 @@ function runtestitem(
10241032 # environment = Module()
10251033 @debugv 1 " Running test item $(repr (name))$(_on_worker ()) ."
10261034 _, stats = @timed_with_compilation _redirect_logs (logs == :eager ? DEFAULT_STDOUT[] : logpath (ti)) do
1027- with_source_path (() -> Core. eval (Main, mod_expr), ti. file)
1028- with_source_path (() -> Core. eval (Main, test_end_mod_expr), ti. file)
1035+ # Always run the test_end_mod_expr, even if the test item fails / throws
1036+ try
1037+ with_source_path (() -> Core. eval (Main, mod_expr), ti. file)
1038+ finally
1039+ has_test_end_expr && @debugv 1 " Running test_end_expr for test item $(repr (name))$(_on_worker ()) ."
1040+ with_source_path (() -> Core. eval (Main, test_end_mod_expr), ti. file)
1041+ end
10291042 nothing # return nothing as the first return value of @timed_with_compilation
10301043 end
10311044 @debugv 1 " Done running test item $(repr (name))$(_on_worker ()) ."
0 commit comments