Tools and Helpers

GdUnit provides several tools to help you write tests, including managing objects to free and accessing a temporary filesystem to store your test data.


auto_free()

A little helper for automatically releasing the objects you create after test execution.

Note that objects do not manage memory. If a class inherits from Object, you will need to delete its instances manually. References keep an internal reference counter so that they are automatically released when no longer in use, and only then. Therefore, you do not need to free references manually with Object.free().

Use auto_free() to automatically release objects when they are no longer in use. Objects that are covered by auto_free only live in the scope where they are used. These scopes include the test suite setup, test case setup, and the tests themselves.

  •     func auto_free(obj :Object) -> Object:
    
  •     public static T AutoFree<T>(T obj);
    

Here’s an small example:

  •     # using auto_free() on Path object to register for freeing after the test is finished
        assert_object(auto_free(Path.new())).is_not_instanceof(Tree)
    
  • using static Assertions;
    
      ...
        // using AutoFree() on Path object to register for freeing after the test is finished
        AssertObject(AutoFree(new Godot.Path())).IsNotInstanceOf<Godot.Tree>();
    

Here’s an extended example of a test suite to demonstrate the usage of auto_free() and freeing memory:

    extends GdUnitTestSuite

    var _obj_a;
    var _obj_b;
    var _obj_c;

    # Scope test suite setup
    func before():
        _obj_a = auto_free(Node.new())
        print_obj_usage("before")

    # Scope test case setup
    func before_test():
        _obj_b = auto_free(Node.new())
        print_obj_usage("before_test")

    # Scope test
    func test():
        _obj_c = auto_free(Node.new())
        # _obj_a still lives here
        # _obj_b still lives here
        # _obj_b still lives here
        print_obj_usage("test")

    # Scope test case setup
    func after_test():
        # _obj_a still lives here
        # _obj_b still lives here
        # _obj_c is freed
        print_obj_usage("after_test")
        
    # Scope test suite setup
    func after():
        # _obj_a still lives here
        # _obj_b is auto freed
        # _obj_c is freed
        print_obj_usage("after")

    func _notification(what):
        if what == NOTIFICATION_PATH_CHANGED:
            print_header()
        else:
            print_obj_usage(GdObjects.notification_as_string(what))

    func print_header() :
        prints("|%16s | %16s | %16s | %16s |" % ["", "_obj_a", "_obj_b", "_obj_c"])
        prints("----------------------------------------------------------------------------")

    func print_obj_usage(name :String) :
        prints("|%16s | %16s | %16s | %16s |" % [name, _obj_a, _obj_b, _obj_c])
State _obj_a _obj_b _obj_c
PARENTED Null Null Null
ENTER_TREE Null Null Null
POST_ENTER_TREE Null Null Null
READY Null Null Null
before [Node:1515] Null Null
before_test [Node:1515] [Node:1519] Null
test [Node:1515] [Node:1519] [Node:1521]
after_test [Node:1515] [Node:1519] [Deleted Object]
after [Node:1515] [Deleted Object] [Deleted Object]
EXIT_TREE [Deleted Object] [Deleted Object] [Deleted Object]
UNPARENTED [Deleted Object] [Deleted Object] [Deleted Object]
PREDELETE [Deleted Object] [Deleted Object] [Deleted Object]

create_temp_dir()

This helper function creates a new directory under the temporary directory user://tmp, which can be useful for storing data during test execution.
The directory is automatically deleted after the test suite has finished executing.

  •     func create_temp_dir(relative_path :String) -> String:
    
  •     public static string CreateTempDir(string path);
    

Here’s an example:

    func test_save_game_data():
        # create a temporay directory to store test data
        var temp_dir := create_temp_dir("examples/game/save")
        var file_to_save := temp_dir + "/save_game.dat"
        
        var data = {
            'user': "Hoschi",
            'level': 42
        }
        var file := File.new()
        file.open(file_to_save, File.WRITE)
        file.store_line(JSON.print(data))
        file.close()
        
            # the data is saved at "user://tmp/examples/game/save/save_game.dat"
        assert_bool(file.file_exists(file_to_save)).is_true()

clean_temp_dir()

Deletes the temporary directory created by create_temp_dir(). This function is called automatically after each execution of the test suite to ensure that the temporary directory is clean and ready for the next test suite.

  •    func clean_temp_dir():
    
  •    public static void ClearTempDir();
    

create_temp_file()

The create_temp_file() function creates a new File under the temporary directory user://tmp + <relative_path> with the given name <file_name> and file <mode> (default = File.WRITE).
If successful, the returned File is automatically closed after the execution of the test suite.
We can create a small test file at the beginning of a test suite in the before() function and read it later in the test. It is not necessary to close the file, as the GdUnit test runner will close it automatically.

    func create_temp_file(relative_path :String, file_name :String, mode :=File.WRITE) -> File:

Here’s an example:

    # setup test data
    func before():
        # opens a tmp file with WRITE mode under "user://tmp/examples/game/game.sav" (auto closed)
        var file := create_temp_file("examples/game", "game.sav")
        assert_object(file).is_not_null()
        # write some example data
        file.store_line("some data")
        # not needs to be manually close, will be auto closed before test execution
        
    func test_create_temp_file():
        # opens the stored tmp file with READ mode under "user://tmp/examples/game/game.sav" (auto closed)
        var file_read := create_temp_file("examples/game", "game.sav", File.READ)
        assert_object(file_read).is_not_null()
        assert_str(file_read.get_as_text()).is_equal("some data\n")
        # not needs to be manually close, will be auto closed after test suite execution

resource_as_array()

This function reads a resource file located at the given path <resource_path> and returns its contents as a PackedStringArray.

    func resource_as_array(resource_path :String) -> PoolStringArray:

Here’s an example:

    var rows = ["row a", "row b"]
    var file_content := resource_as_array("res://myproject/test/resources/TestRows.txt")
    assert_array(rows).contains_exactly(file_content)

resource_as_string()

This function reads a resource file located at the given path <resource_path> and returned the content as String.

    func resource_as_string(resource_path :String) -> String:

Here’s an example:

    var rows = "row a\nrow b\n"
    var file_content := resource_as_string("res://myproject/test/resources/TestRows.txt")
    assert_string(rows).is_equal(file_content)

document version v4.1.0


Copyright © 2021-2024 Mike Schulze. Distributed by an MIT license.