-
Notifications
You must be signed in to change notification settings - Fork 108
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add_sibling() - Warns of orphans - Might need a new assert_new_orphans(nb_orphans) #584
Comments
You should free the children at the end of the test. In the case of using
add sibling, you could create a parent node that gets autofreed, so you
don't have to free each one manually.
```
var temp = add_child_autofree(Node2D.new())
temp.add_child(potato)
...
```
…On Sat, Mar 30, 2024, 2:33 PM Maxime Dupuis ***@***.***> wrote:
Using Node.add_sibling
<https://docs.godotengine.org/en/stable/classes/class_node.html#class-node-method-add-sibling>
results in an orphans warning:
Reproduce
potato.gd
extends Node
class_name Potato
func spawn_another_potato() -> void:
add_sibling(Potato.new())
test_potato.gd
extends GutTest
func test_spawn_another_potato() -> void:
var potato: Potato = add_child_autofree(Potato.new())
potato.spawn_another_potato()
assert_eq(get_child_count(), 2)
Current behaviour
res://test/unit/test_potato.gd
* test_spawn_another_potato
[Passed]: [2] expected to equal [2]:
[WARNING]: Test script still has children when all tests finisehd.
@***@***.***:<Node#44845499894>(potato.gd)
You can use autofree, autoqfree, add_child_autofree, or add_child_autoqfree to automatically free objects.
1/1 passed.
[......]
[Orphans]: 1 new orphan in total.
Note: This count does not include GUT objects that will be freed upon exit.
It also does not include any orphans created by global scripts
loaded before tests were ran.
Total orphans = 2
Expected behaviour?
The orphans count warnings is useful to catch bugs or unexpected nodes
being created. But in some cases, creating orphans is the expected
behaviour, for example if a bullet splits into multiple bullets.
I'm not sure what the right behaviour should be, here are some ideas
- Tell the test how many orphans are expected with
assert_new_orphans(nb_orphans). Do not produce warning if the count is
OK.
- If using add_sibling() is a bad practice, document an alternative
—
Reply to this email directly, view it on GitHub
<#584>, or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAI2LKFC6JJ2LLLWAQMDKDLY24AOLAVCNFSM6AAAAABFPX2JTGVHI2DSMVQWIX3LMV43ASLTON2WKOZSGIYTMNRRG4YTOMY>
.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
|
The main reason you should free the children is so that state does not leak from one test to the other. For example, if you had a method called extends GutTest
func test_spawn_another_potato() -> void:
var potato: Potato = add_child_autofree(Potato.new())
# Adds a child to this test that isn't freed
potato.spawn_another_potato()
assert_eq(get_child_count(), 2)
func test_spawn_two_more_potato() -> void:
var potato: Potato = add_child_autofree(Potato.new())
# Adds two more children that aren't freed
potato.spawn_two_more_potatoes()
# This will fail b/c the extra potato from the first test was not freed.
# The actual count will be 4.
assert_eq(get_child_count(), 3) |
Yes that works, or we can do my current workaround:
|
Are you aware of a use-case where someone would NOT want to free all children? => By default all children get deleted after each test. Deprecate the need to use |
It's not easy to express with just an isolated example. But imagine a bigger project, with many tests instantiating a object that might add siblings. For a concrete example, in my game, every time you hit something with a sword, the sword might break, which adds sword shards as siblings. Tons of tests use a sword to hit tons of stuff. So it becomes cumbersome to handle orphans, even in tests where the shards are not the focus. E.g. when hitting something then it is knocked back. |
After each test? Yes. You may want a few things to stick around for all tests in a script/inner class. This is why the warning is shown after all tests in a script are run, and not after each test. There are cases where you may want to setup a reusable nodes in
I think the best way to handle this kind of thing is to create a parent node that everything is added to instead of adding to the test node. Maybe something like this: var _temp_parent = null
func before_each():
_temp_parent = Node2D.new()
add_child_autofree(_temp_parent)
func test_something():
var sword = Sword.instantiate()
_temp_parent.add_child(sword)
... This gets you a new parent for all your siblings in each test and the parent is freed automatically after each test.
There are two things that The only change to GUT that I think makes sense would be to free test scripts after they complete. I think I'd still issue the warning if there were children at the end, but this would address the build-up of nodes and the chance that these nodes could pollute other tests. |
I agree that it's good testing practice to clear children between scripts. And it's usually a good practice to clear them between each test. Good tests should be independent. I think GUT should nudge people towards these good practices. It should be the default. normal_test.gd
special_case_test.gd
In my opinion, the only downside is it would be a breaking change for anyone relying on the current behaviour. |
I think this would break a lot of test suites. I think it would be best to add some documentation around the warning, or improve the warning text, so that it's clear how GUT should be used. The real fix is probably to free the test scripts after they are done, though the warning should stick around. |
Yeah that's a tricky one to avoid breaking existing tests. IF you agree GUT should clear children between each test, maybe it could be in the next major version. Meanwhile people can use workarounds. Possibly have a GUT config option that defaults to the current behaviour but make it possible to toggle the new behaviour. Or maybe it's just against the project's philosophy. Better to keep GUT consistent even if it adds a little friction for my use case. |
Using Node.add_sibling results in an orphans warning:
Reproduce
potato.gd
test_potato.gd
Current behaviour
Expected behaviour?
The orphans count warnings is useful to catch bugs or unexpected nodes being created. But in some cases, creating orphans is the expected behaviour, for example if a bullet splits into multiple bullets.
I'm not sure what the right behaviour should be, here are some ideas
assert_new_orphans(nb_orphans)
. Do not produce warning if the count is OK.add_sibling()
is a bad practice, document an alternativeThe text was updated successfully, but these errors were encountered: