Open4

Godotのテストコード(Gut)の小技集

ピン留めされたアイテム
tkmfujisetkmfujise

基本の書き方

src/player/player.gd
extends CharacterBody2D

func get_state() -> String:
	if velocity:
		if velocity.y < 0: return 'Jump'
		if velocity.y > 0: return 'Fall'
		else: return 'Run'
	else: return 'Idle'
test/player/test_player.gd
extends GutTest

var PlayerScene = load("res://src/player/player.tscn")
var scene = null

func before_each():
	scene = PlayerScene.instantiate()
	add_child(scene)

func after_each():
	if scene: scene.free()

func test_get_state_if_move():
	scene.velocity = Vector2(1, 0)
	assert_eq(scene.get_state(), 'Run')

導入方法については以下参照
https://zenn.dev/tkmfujise/articles/6561fa98824a04#テストコード

tkmfujisetkmfujise

Signal が実行される前提のコードをテストしたい場合は、wait_for_signal を使う。
https://gut.readthedocs.io/en/latest/Awaiting.html#wait-for-signal

scr/beginning/screen/screen.gd
var current_animation : StringName

func _on_animation_tree_animation_started(anim_name: StringName) -> void:
	current_animation = anim_name
test/beginning/screen/test_screen.gd
# 略
func animation_signal() -> Signal:
	return scene.get_node('%AnimationTree').animation_started

func test_ready():
	assert_not_null(scene)
	await wait_for_signal(animation_signal(), 1)
	assert_eq(scene.get_node('%Author').visible, true)
	assert_eq(scene.get_node('%Title').visible, false)
	assert_eq(scene.current_animation, 'opening')
tkmfujisetkmfujise

Signal が発行されること自体をテストしたい場合は、watch_signals, assert_signal_emitted_with_parameters を使う。
https://gut.readthedocs.io/en/latest/Asserts-and-Methods.html#watch-signals-object

src/books/books.gd
func add_book(book: DB_Record):
	var index = %BookList.add_item(book.name, book_icon)
	%BookList.set_item_metadata(index, book.attributes())

func select_book_at(index: int):
	var metadata = %BookList.get_item_metadata(index)
	book_selected.emit(metadata)
test/books/test_books.gd
func test_select_book():
	var record = DB.Book.create({ "name": "test" })
	watch_signals(scene)
	scene.select_book_at(0)
	assert_signal_emitted_with_parameters(scene,
		'book_selected',
		[record.attributes()])
tkmfujisetkmfujise

アサーションの追加

GutTest を継承したクラスにメソッド追加。テストコードではそっちを呼ぶようにする。

test/gut_test_meta.gd
extends GutTest
class_name GutTestMeta

func assert_match(val, str):
	var regex = RegEx.new()
	regex.compile(str)
	assert_not_null(regex.search(val))


func assert_match_time_str(val):
	assert_match(val, '^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$')
extends GutTestMeta

func test_now_str():
	var str = TimeHelper.now_str()
	assert_typeof(str, TYPE_STRING)
	assert_match(str, '^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$')
extends GutTestMeta

func test_set_timestamp():
	var record = DB.Project.new_record()
	record.set_timestamp()
	assert_match_time_str(record.created_at)
	assert_match_time_str(record.updated_at)