GDScript Warnings
GUT has a bit of legacy code in it. I’m pretty proud that GUT has existed long enough to have legacy code, but that means GUT development hasn’t benefited from all the warnings that Godot has introduced over the years. GUT also has to do some things that you shouldn’t normally do.
Godot introduced a directory_rules setting in Project Settings->Debug->GDScript (requires “Advance Settings” to be enabled to edit). This allows you to define which directories should be included/excluded when applying your warning settings. By default res://addons is excluded. Godot recommends you leave this setting and then add any directories in the addons directory that you want included.

GUT does some warning management when executing tests. This alleviates clashes between your project’s warnings and the warnings that GUT triggers.
When a run starts, prior to loading most of the scripts in GUT,
res://addons/gutis added todirectory_rulesas “Exclude”. This only affects the Project Settings while running tests, and is not saved.Before each test script is loaded, all warnings are disabled. They are re-enabled after the script is loaded.
All warnings are disabled when creating doubles of objects.
If you are concerned that these GUT is hiding warnings in your own scripts during a test run, you can create a standalone script to generate all warnings for your code using something like this:
# ------------------------------------------------------------------------------
# This script loads scripts so you can see a list of all the warnings that
# are generated by your scripts.
# * Sets all ERROR warnings to WARN
# * Loads all scripts in "res" and all subdirectories (by default)
# * If you specify a path after the script it will load that path instead
#
# You must run this script with the -d option or errors/warnings are not
# printed by Godot.
#
# Example:
# godot -d -s path/to/this/script.gd
# godot -d -s path/to/this/script.gd res://addons/my_addon
# ------------------------------------------------------------------------------
extends SceneTree
var include_subdirectories := true
const GDSCRIPT_WARNING = 'debug/gdscript/warnings/'
# ------------------------------------------------------------------------------
# Gets all the files in a directory and all subdirectories if include_subdirectories
# is true. The files returned are all sorted by name.
# ------------------------------------------------------------------------------
func get_files(path: String, prefix: String, suffix: String) -> Array[String]:
var files: Array[String] = []
var directories: Array[String] = []
var d := DirAccess.open(path)
d.list_dir_begin()
# Traversing a directory is kinda odd. You have to start the process of listing
# the contents of a directory with list_dir_begin then use get_next until it
# returns an empty string. Then I guess you should end it.
var fs_item := d.get_next()
var full_path := ''
while fs_item != '':
full_path = path.path_join(fs_item)
#file_exists returns fasle for directories
if d.file_exists(full_path):
if fs_item.begins_with(prefix) and fs_item.ends_with(suffix):
files.append(full_path)
elif include_subdirectories and d.dir_exists(full_path):
directories.append(full_path)
fs_item = d.get_next()
d.list_dir_end()
for dir in range(directories.size()):
var dir_files := get_files(directories[dir], prefix, suffix)
for i in range(dir_files.size()):
files.append(dir_files[i])
files.sort()
return files
func set_all_errors_to_warnings() -> void:
var props := ProjectSettings.get_property_list()
for prop in props:
var prop_name: String = prop.name
var prop_hint_string: String = prop.hint_string
if prop_name.begins_with(GDSCRIPT_WARNING) and\
prop_hint_string == 'Ignore,Warn,Error' and \
ProjectSettings.get_setting(prop_name) == 2:
print('Changed [', prop_name.replace(GDSCRIPT_WARNING, ''), '] to WARN')
ProjectSettings.set_setting(prop_name, 1)
func load_all_scripts(path:String) -> void:
var files := get_files(path, '', '.gd')
for f in files:
print("---- ", f, " ----")
var _thing := load(f)
# get_cmdline_args always has -s as first and the script path as the second
# argument. All other arguments used by the engine do not appear in
# get_cmdline_args.
#
# This treats the 3rd argument as the directory. All other arguments are
# ignored.
func get_directory_to_load(default) -> String:
var args = OS.get_cmdline_args()
var to_return = default
if(args.size() > 2):
to_return = args[2]
return to_return
func _init() -> void:
if(EngineDebugger.is_active()):
var dir = get_directory_to_load('res://')
print('Loading scripts from ', dir)
set_all_errors_to_warnings()
load_all_scripts(dir)
else:
print("This script must be run with -d flag or warnings/errors will not be displayed.")
quit()