testkit

package
v0.6.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 6, 2026 License: MIT Imports: 19 Imported by: 0

Documentation

Overview

Package testkit provides a testing framework for autoebiten games.

testkit offers two testing modes:

  1. Black-Box Testing (Game): Launches the game in a separate process and controls it via JSON-RPC over Unix sockets. This mode tests the game as a black box, identical to how real users interact with it.

  2. White-Box Testing (Mock): Tests game logic in the same process with mocked inputs. This mode provides fine-grained control over game state and is ideal for unit testing specific behaviors.

Both modes use a similar API for input injection (key presses, mouse movements) and state observation, allowing tests to be written in a mode-agnostic way.

Example black-box test:

func TestPlayerMovement(t *testing.T) {
    game := testkit.Launch(t, "./mygame", testkit.WithTimeout(30*time.Second))
    defer game.Shutdown()

    // Wait for game to be ready
    game.WaitFor(func() bool {
        err := game.Ping()
        return err == nil
    }, 5*time.Second)

    // Press movement key for 10 ticks
    game.HoldKey(ebiten.KeyArrowRight, 10)

    // Verify player moved
    x, err := game.StateQuery("gamestate", "Player.X")
    require.NoError(t, err)
    assert.Greater(t, x.(float64), 0.0)
}

Example white-box test:

func TestPlayerMovement(t *testing.T) {
    myGame := NewMyGame()
    mock := testkit.NewMock(t, myGame)

    // Inject key press
    mock.InjectKeyPress(ebiten.KeyRight)

    // Advance 10 ticks
    mock.Ticks(10)

    // Verify player moved
    assert.Greater(t, myGame.Player.X, 0)
}

State Export:

Games can export internal state using autoebiten.RegisterStateExporter, which enables reflection-based state queries via dot-notation paths like "Player.X" or "Inventory.0.Name":

func init() {
    autoebiten.RegisterStateExporter("gamestate", &gameInstance)
}

Index

Constants

This section is empty.

Variables

View Source
var ErrGameNotRunning = errors.New("game is not running")

ErrGameNotRunning is returned when an operation is attempted on a game that has not been launched or has already shut down.

View Source
var ErrInvalidState = errors.New("invalid game state")

ErrInvalidState is returned when the game is in an invalid state for the requested operation.

View Source
var ErrTimeout = errors.New("operation timed out")

ErrTimeout is returned when an operation times out.

Functions

This section is empty.

Types

type Game

type Game struct {
	// contains filtered or unexported fields
}

Game provides black-box testing control over a game running in a separate process. It communicates with the game via JSON-RPC over Unix sockets.

func Launch

func Launch(t *testing.T, binaryPath string, opts ...Option) *Game

Launch starts a game binary in a separate process and returns a Game controller. The game must be an autoebiten-enabled game that listens on the Unix socket.

The Game is automatically cleaned up when the test ends via t.Cleanup(). Callers can also manually call Shutdown() for early cleanup.

Options:

  • WithTimeout: sets timeout for operations (default 30s)
  • WithArgs: adds command-line arguments
  • WithEnv: sets environment variables

func (*Game) HoldKey

func (g *Game) HoldKey(key ebiten.Key, ticks int64) error

HoldKey holds a key down for the specified number of ticks.

func (*Game) MoveMouse

func (g *Game) MoveMouse(x, y int) error

MoveMouse moves the mouse cursor to the specified position.

func (*Game) Ping

func (g *Game) Ping() error

Ping checks if the game is responsive. Returns an error if the game is not running or not responding.

func (*Game) PressKey

func (g *Game) PressKey(key ebiten.Key) error

PressKey sends a key press event to the game.

func (*Game) PressMouseButton

func (g *Game) PressMouseButton(button ebiten.MouseButton) error

PressMouseButton sends a mouse button press event.

func (*Game) ReleaseKey

func (g *Game) ReleaseKey(key ebiten.Key) error

ReleaseKey sends a key release event to the game.

func (*Game) ReleaseMouseButton

func (g *Game) ReleaseMouseButton(button ebiten.MouseButton) error

ReleaseMouseButton sends a mouse button release event.

func (*Game) RunCustom

func (g *Game) RunCustom(name, request string) (string, error)

RunCustom executes a custom command registered by the game.

func (*Game) Screenshot

func (g *Game) Screenshot() (*image.RGBA, error)

Screenshot captures the current game screen and returns it as an image.

func (*Game) ScreenshotBase64

func (g *Game) ScreenshotBase64() (string, error)

ScreenshotBase64 captures the current game screen and returns it as a base64 string.

func (*Game) ScreenshotToFile

func (g *Game) ScreenshotToFile(path string) error

ScreenshotToFile captures the current game screen and saves it to a file.

func (*Game) ScrollWheel

func (g *Game) ScrollWheel(x, y float64) error

ScrollWheel sends a wheel scroll event.

func (*Game) Shutdown

func (g *Game) Shutdown() error

Shutdown gracefully terminates the game process. It first attempts SIGTERM, then falls back to SIGKILL if needed.

func (*Game) StateQuery

func (g *Game) StateQuery(name string, path string) (any, error)

StateQuery queries game state via reflection-based path. The path uses dot notation, e.g., "Player.X", "Inventory.0.Name".

func (*Game) WaitFor

func (g *Game) WaitFor(fn func() bool, timeout time.Duration) bool

WaitFor polls the provided function until it returns true or the timeout is reached. The function is called every 100ms.

type GameUpdate

type GameUpdate interface {
	Update() error
}

GameUpdate is the interface required for Mock white-box testing. Games must implement at least an Update method.

type Mock

type Mock struct {
	// contains filtered or unexported fields
}

Mock provides white-box testing control over a game running in the same process. It injects inputs directly into the game's update loop without requiring RPC.

func NewMock

func NewMock(t *testing.T, game GameUpdate) *Mock

NewMock creates a new Mock controller for white-box testing. The provided game must implement at least Update() error.

The Mock is automatically cleaned up when the test ends via t.Cleanup().

func (*Mock) Game

func (m *Mock) Game() GameUpdate

Game returns the underlying game instance. This allows direct access to game state for assertions.

func (*Mock) InjectKeyPress

func (m *Mock) InjectKeyPress(key ebiten.Key)

InjectKeyPress buffers a key press event to be applied on the next Tick.

func (*Mock) InjectKeyRelease

func (m *Mock) InjectKeyRelease(key ebiten.Key)

InjectKeyRelease buffers a key release event to be applied on the next Tick.

func (*Mock) InjectMouseButtonPress

func (m *Mock) InjectMouseButtonPress(button ebiten.MouseButton)

InjectMouseButtonPress buffers a mouse button press event.

func (*Mock) InjectMouseButtonRelease

func (m *Mock) InjectMouseButtonRelease(button ebiten.MouseButton)

InjectMouseButtonRelease buffers a mouse button release event.

func (*Mock) InjectMousePosition

func (m *Mock) InjectMousePosition(x, y int)

InjectMousePosition sets the mouse cursor position.

func (*Mock) InjectWheel

func (m *Mock) InjectWheel(x, y float64)

InjectWheel sets the wheel scroll delta.

func (*Mock) Tick

func (m *Mock) Tick()

Tick advances the game by one tick, applying buffered inputs. This calls the game's Update() method once.

func (*Mock) Ticks

func (m *Mock) Ticks(n int)

Ticks advances the game by N ticks. This is equivalent to calling Tick() N times.

type Option

type Option func(*config)

Option configures Launch behavior.

func WithArgs

func WithArgs(args ...string) Option

WithArgs sets additional command-line arguments for the game binary.

func WithEnv

func WithEnv(key, value string) Option

WithEnv sets environment variables for the game process. These are added to the current environment, not replacing it.

func WithTimeout

func WithTimeout(d time.Duration) Option

WithTimeout sets the timeout for game operations. Default is 30 seconds.

Directories

Path Synopsis
internal

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL