Skip to content

Add documentation for setting global per-test hooks in pre-run hook#804

Open
Curtis-Barnhart wants to merge 3 commits intobitwes:mainfrom
Curtis-Barnhart:762-global-lifecycle-hooks-docs
Open

Add documentation for setting global per-test hooks in pre-run hook#804
Curtis-Barnhart wants to merge 3 commits intobitwes:mainfrom
Curtis-Barnhart:762-global-lifecycle-hooks-docs

Conversation

@Curtis-Barnhart
Copy link
Contributor

resolves #762

Coming from #794 you suggested that instead of adding time_scale modification to GUT it may be better to write documentation about how one could add it themselves since time_scale can be quite difficult to work with. You suggested it may also be appropriate to consider documenting the signals/hooks discussed in 762 and referencing those in documentation of time_scale. It seemed natural to work on the global hooks documentation first, which this PR addresses.

I added a subsection under the "hooks" wiki page describing how to use the pre-run hook to set up hooks into the signals fired before/after each test script/method. Because the signals in GutMain were previously undocumented and inaccessible to anyone not digging through the source code, I added documentation for them as well in the class reference.

Because it may be very helpful to understand the order in which the normal before_all, after_all, ... hooks are run in compared to the signals GutMain emits, the documentation I added of these signals lays out the order, and I also added a test of GutMain to ensure the order in which these hooks and signals are called is well defined. One thing that you may want to look at is that currently, the pattern that the hook/signal call order is in is that a hook is always called before its equivalent signal, except for the start_script signal, which is run before the before_all hook. It might make things more organized if all the hooks/signals followed the same call order pattern, and if you'd like me to make them conform to some pattern (whether it is hooks before signals or signals sandwiching hooks) I can definitely change that.

Of slightly less importance, I added some notes to the documentation README explaining how to link to headers in the same and in other markdown files, because you already had a note explaining how to link to other markdown files and I didn't know how to link to headers before I started this PR, and I thought it might be useful to someone in the future who doesn't want to look this up. This is lookup-able though, so if you want me to remove it I can do that as well.

Also, I thought this would resolve 762, but your last comment there did say "The new hooks scripts might still be a good idea, but I think you do everything you want with the existing ones." so I'm not sure if you fully believe this is worth closing 762 over. If adding other hooks is something you'd want to do in the future, feel free to edit this PR to remove the resolution at the top.

@Curtis-Barnhart Curtis-Barnhart force-pushed the 762-global-lifecycle-hooks-docs branch 2 times, most recently from b7817d7 to fd8f426 Compare February 7, 2026 20:07
@bitwes
Copy link
Owner

bitwes commented Feb 19, 2026

Thanks for starting this.

I would be ok with a new wiki page for "Global Lifecycle Hooks" (or any better name). This keeps everything in one place and we can integrate into the Hooks page later, once it becomes a more formal feature.
I'd like the page to have the following:

  • A disclaimer that this is a workaround for these things not formally existing in GUT yet.
  • The execution order of signals and setup/teardown methods (as per the test you added, nice test btw).
  • A tested version of the sample code I put in Global lifecycle hooks #762. This can be manually tested, but we should know if it works before making formal documentation.
  • Link to collected_script.gd for documentation purposes, noting that it's not really for general consumption.
  • A "call to action" at the end that encourages readers to open issues for improvements.

Issues with the current system

These signals were added to decouple the GUI from GutMain, so they might not have the right timing to be useful (and your point about inconsistent ordering of signal emission and setup/teardown methods). We almost certainly need a signal that sends the GutTest instance instead of a collected_script.gd instance. Right now, there is no way to get a reference to the test script instance prior to the first emission of start_test (and you have to go through an undocumented method to do so).

New system

The changes you proposed are valid, but I think it's probably better to consider a new approach instead of making the existing stuff work.

I'm thinking a new GutPreRunHookScript script and adding virtual methods for each of these "hooks" sounds promising. By adding in these hooks, I think the "pre" and "post" scripts are diverging enough to justify a new class. The GutPreRunHookScript would inherit from GutHookScript and GUT would accept either class as a valid pre-run hook script. It would not accept GutPreRunHookScript as a valid post-run hook script.

And that's about as far as I've thought about it.

@Curtis-Barnhart
Copy link
Contributor Author

Hm, so to be clear on what you're looking for, you're saying that for now it will do to have a dedicated "Global Lifecycle Hooks" wiki page documenting the current somewhat makeshift signals solution (and your other bullet points in that first section) (which sounds within the scope of this PR). Later, as a more permanent solution (and a separate PR), instead of exposing the signals, we could in this new GutPreRunHookScript class have virtual methods that the user can override to be called at the specified lifecycle event (and also sort out the order of hooks here). Is this correct?

@bitwes
Copy link
Owner

bitwes commented Feb 20, 2026

Exactly.

@Curtis-Barnhart Curtis-Barnhart force-pushed the 762-global-lifecycle-hooks-docs branch from 65c05a9 to 56bc171 Compare February 22, 2026 17:40
@Curtis-Barnhart
Copy link
Contributor Author

I've made a new wiki page specifically for the global lifecycle hooks, where the example pre-hook script you gave is shown. The example pre-hook script is also added as a test to ensure it actually does what we claim it does in the docs. How does this look to you?

Copy link
Owner

@bitwes bitwes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks pretty good. I made some adjustments. Let me know if you have any thoughts about them. Thanks.

Comment on lines +5 to +8
This page describes workarounds for missing features in GUT
that are not planned to be long term solutions.
Eventually this same functionality will be available
through a more formally supported system.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's unclear if the workarounds or the missing features "are not planned". Maybe:

"This page describes how to use existing signals to perform logic at various stages of test execution. Eventually, a more formal mechanism will be implemented. See Issue 762 for more details.

Comment on lines +11 to +33

GUT does not expose "global" function hooks that can be run before each test script or method
-- while GutTest exposes [hooks](Creating-Tests.md#details)
to run code before/after each test method/class,
these must be set on every GutTest instance you want the behavior for.

However, GutMain _does_ expose <a href="class_ref/class_gutmain.html#signals">signals</a>
that have the same effect on a global level,
being emitted at the beginning/end of all test scripts/methods.
By connecting custom functions to these signals during the [Pre-Run Hook](Hooks.md#pre-run-hook),
you can call custom code in hooks across every GutTest instance while defining it only once.
Following is an example of how you would write a pre-run hook script to set up a global setup function.

```gdscript
extends GutHookScript

func run():
gut.start_test.connect(_on_test_started)

func _on_test_started(test_name):
# setup logic run before every test in every test script goes here
```

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The gut instance accessible in a Pre-Run Hook has the following signals that can be connected to. These signals were not intended to be used for this purpose, but it's what we have until a more formal solution exists.

signal start_run
signal end_run
## Emitted before every test script is run. Emitted before [method GutTest.before_all] hook on test is run.
## test_script_obj is an instance of addons/gut/collected_script.gd.
signal start_script(test_script_obj)
## Emitted after every test script is run. Emitted after [method GutTest.after_all] hook on test is run.
signal end_script
## Emitted before every test method is run. Emitted after [method GutTest.before_each] hook on test is run.
## test_name is the string name of the current test about to be started.
signal start_test(test_name)
## Emitted after every test method is run. Emitted after [method GutTest.after_each] hook on test is run.
signal end_test

Comment on lines +127 to +131
The `start_script` signal contains an object `test_script_obj` which is an instance of
the [collected_script.gd](https://github.com/bitwes/Gut/blob/main/addons/gut/collected_script.gd) class,
which may be found at `addons/gut/collected_script.gd`.
This class is not intended for public consumption,
so use this value at your own risk.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The start_script signal is passed an instance of the collected_script.gd class. This is NOT the instance of the test script. This class is not intended for public consumption, so use this value at your own risk.


signal start_run
signal end_run
## Emitted before every test script is run. Emitted before [method GutTest.before_all] hook on test is run.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Emitted before every test script instance is created. Emitted before [method GutTest.before_all] hook on test is run.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Global lifecycle hooks

2 participants