Your problem seems a legitimate call for assertz/retract.
These builtins allow to track the chronological sequence, and to store arbitrary Prolog terms, then you could write
:- dynamic results/2.
test(a) :- a_code(Result), assertz(results(a, Result)).
test(b) :- b_code(Result), assertz(results(b, Result)).
test(c) :- test(a), test(b), test(a).
test(c) :- test(a), test(a).
check_results :- forall(retract(Name, Result), writeln(Name = Result)).
If you want to track failed executions, you can extend that schema:
test(a) :- a_code(Result) -> assertz(results(ok(a), Result)) ; assertz(results(ko(a), _)).
test(b) :- b_code(Result) -> assertz(results(ok(b), Result)) ; assertz(results(ko(b), _)).