Skip to content
Agent Orchestration
Skill

/test-helpers

Generate engine-specific test helper libraries for the project's test suite. Reads existing test patterns and produces tests/helpers/ with assertion utilities, factory functions, and mock objects tailored to the project's systems. Reduces boilerplate in new test files.

From plugin
claude-code-game-studios
25k73 skills49 agents
Install
$ npx -y skills add Donchitos/Claude-Code-Game-Studios --skill test-helpers --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/test-helpers

Context preview

The summary Claude sees to decide when to auto-load this skill.

Generate engine-specific test helper libraries for the project's test suite. Reads existing test patterns and produces tests/helpers/ with assertion utilities, factory functions, and mock objects tailored to the project's systems. Reduces boilerplate in new test files.

SKILL.md

test-helpers.SKILL.md
name: test-helpers
description: "Generate engine-specific test helper libraries for the project's test suite. Reads existing test patterns and produces tests/helpers/ with assertion utilities, factory functions, and mock objects tailored to the project's systems. Reduces boilerplate in new test files."
argument-hint: "[system-name | all | scaffold]"
user-invocable: true
allowed-tools: Read, Glob, Grep, Write
model: sonnet

Test Helpers

Writing test cases is faster and more consistent when common setup, teardown, and assertion patterns are abstracted into helpers. This skill generates a `tests/helpers/` library tailored to the project's actual engine, language, and systems — so every developer writes less boilerplate and more assertions.

**Output:** `tests/helpers/` directory with engine-specific helper files

**When to run:**

  • After `/test-setup` scaffolds the framework (first time)
  • When multiple test files repeat the same setup boilerplate
  • When starting to write tests for a new system

---

1. Parse Arguments

**Modes:**

  • `/test-helpers [system-name]` — generate helpers for a specific system

(e.g., `/test-helpers combat`)

  • `/test-helpers all` — generate helpers for all systems with test files
  • `/test-helpers scaffold` — generate only the base helper library (no

system-specific helpers); use this on first run

  • No argument — run `scaffold` if no helpers exist, else `all`

---

2. Detect Engine and Language

Read `.claude/docs/technical-preferences.md` and extract:

  • `Engine:` value
  • `Language:` value
  • `Framework:` from the Testing section

If engine is not configured: "Engine not configured. Run `/setup-engine` first."

---

3. Load Existing Test Patterns

Scan the test directory for patterns already in use:

Glob pattern="tests/**/*_test.*" (all test files)

For a representative sample (up to 5 files), read the test files and extract:

  • Setup patterns (how `before_each` / `setUp` / fixtures are written)
  • Common assertion patterns (what is being asserted most often)
  • Object creation patterns (how game objects or scenes are instantiated in tests)
  • Mock/stub patterns (how dependencies are replaced)

This ensures generated helpers match the project's existing style, not a generic template.

Also read:

  • `design/gdd/systems-index.md` — to know which systems exist
  • In-scope GDD(s) — to understand what data types and values need testing
  • `docs/architecture/tr-registry.yaml` — to map requirements to tested systems

---

4. Generate Engine-Specific Helpers

Godot 4 (GDUnit4 / GDScript)

**Base helper** (`tests/helpers/game_assertions.gd`):

## Game-specific assertion utilities for [Project Name] tests.
## Extends GdUnitAssertions with domain-specific helpers.
##
## Usage:
##   var assert = GameAssertions.new()
##   assert.health_in_range(entity, 0, entity.max_health)

class_name GameAssertions
extends RefCounted

## Assert a value is within the inclusive range [min_val, max_val].
## Use for any formula output that has defined bounds in a GDD.
static func assert_in_range(
    value: float,
    min_val: float,
    max_val: float,
    label: String = "value"
) -> void:
    assert(
        value >= min_val and value <= max_val,
        "%s %.2f is outside expected range [%.2f, %.2f]" % [label, value, min_val, max_val]
    )

## Assert a signal was emitted during a callable block.
## Usage: assert_signal_emitted(entity, "health_changed", func(): entity.take_damage(10))
static func assert_signal_emitted(
    obj: Object,
    signal_name: String,
    action: Callable
) -> void:
    var emitted := false
    obj.connect(signal_name, func(_args): emitted = true)
    action.call()
    assert(emitted, "Expected signal '%s' to be emitted, but it was not." % signal_name)

## Assert that a callable does NOT emit a signal.
static func assert_signal_not_emitted(
    obj: Object,
    signal_name: String,
    action: Callable
) -> void:
    var emitted := false
    obj.connect(signal_name, func(_args): emitted = true)
    action.call()
    assert(not emitted, "Expected signal '%s' NOT to be emitted, but it was." % signal_name)

## Assert a node exists at path within a parent.
static func assert_node_exists(parent: Node, path: NodePath) -> void:
    assert(
        parent.has_node(path),
        "Expected node at path '%s' to exist." % str(path)
    )

**Factory helper** (`tests/helpers/game_factory.gd`):

## Factory functions for creating test game objects.
## Returns minimal objects configured for unit testing (no scene tree required).
##
## Usage: var player = GameFactory.make_player(health: 100)

class_name GameFactory
extends RefCounted

## Create a minimal player-like object for testing.
## Override fields as needed.
static func make_player(health: int = 100) -> Node:
    var player = Node.new()
    player.set_meta("health", health)
    player.set_meta("max_health", health)
    return player

**Scene helper** (`tests/helpers/scene_runner_helper.gd`):

## Utilities for scene-based integration tests.
## Wraps GdUnitSceneRunner for common patterns.

class_name SceneRunnerHelper
extends GdUnitTestSuite

## Load a scene and wait one frame for _ready() to complete.
func load_scene_and_wait(scene_path: String) -> Node:
    var scene = load(scene_path).instantiate()
    add_child(scene)
    await get_tree().process_frame
    return scene

---

Unity (NUnit / C#)

**Base helper** (`tests/helpers/GameAssertions.cs`):

using NUnit.Framework;
using UnityEngine;

/// <summary>
/// Game-specific assertion utilities for [Project Name] tests.
/// Extends NUnit's Assert with domain-specific helpers.
/// </summary>
public static class GameAssertions
{
    /// <summary>
    /// Assert a value is within an inclusive range [min, max].
    /// Use for any formula output defined in GDD Formulas sections.
    /// </summary>
    public static void AssertInRange(float value, float min, float max, string label = "value")
Read more
Ships withclaude-code-game-studios

Turn Claude Code into a full game dev studio — 49 AI agents, 72 workflow skills, and a complete coordination system mirroring real studio hierarchy.

Get the whole plugin

Other skills on claude-code-game-studios.