Skip to content

Testing

Running tests

All commands run from the ftl-backend/ root.

# Full suite: verbose, race detector, no cache
make test

# Short suite: skips slow integration tests
make test-short

# Coverage report (generates coverage.html)
make test-coverage

The make test target maps to:

go test ./... -v -race -count=1

-race enables the Go race detector. -count=1 disables test caching so every run is fresh.

make test-short maps to:

go test ./... -short -v

Tests that call testing.Short() skip database or Redis operations when this flag is set.

Running a single test

go test ./internal/auth/ -run TestJWTIssuer -v
go test ./internal/trade/ -run TestExecuteLua -v -race
go test ./internal/positions/ -run TestStopWatch -v

Test layout

Each package under internal/ has _test.go files alongside the implementation. Tests that need Postgres or Redis use the DATABASE_URL and REDIS_URL environment variables.

Packages with test coverage:

Package Test domains
achievements Badge award logic
activity Feed publish and read
adminsettings Setting persistence and OnUpdate callbacks
amm AMM fill price arithmetic
auth JWT issue and validate, blocklist, reg ticket, Google token parsing
config Env parsing, validation edge cases
email Template rendering
handler HTTP handler integration (auth, registration flow)
leaderboard Leaderboard sorted set reads
lease Redis lease acquire/release
margin Washout replay logic, equity computation
match Fixture and squad queries
middleware JWTAuth, RateLimit, AdminOnly
otp OTP issue, verify, cooldown, verified-flag
positions CFD open/close Lua, StopWatch SL/TP, lot-size validation, modify, ghost cleanup
referral Code validation, first-trade payout
sportmonks Post-match processor, scoring
trade trade_execute.lua via Redis, sell cooldown
user Registration, district validation
ws Hub subscribe/unsubscribe, pub/sub routing
xp XP award and level thresholds

Fixtures

The internal/replay/fixtures/ directory contains bundled match replay scenarios:

File Scenario
fck_vejle.json Standard fixture with goals and cards
high_action.json High-event match for scoring stress
low_action.json Quiet match for noise-only price movement

The admin gameplay-bot feature (AdminGameplayBotStart) uses these fixtures to replay a match without a live Sportmonks connection. Tests in internal/replay/ use the same files.

Environment for tests

Tests that hit Postgres or Redis read from the environment:

export DATABASE_URL="postgres://ftl_admin:localdev@localhost:5432/ftl2026?sslmode=disable"
export REDIS_URL="redis://localhost:6379"
make test

Without these, tests that do not call testing.Short() will fail to connect. The make test target assumes a local database and Redis are available via ftl.sh.

Tip

Run make test-short when you do not have a local Postgres or Redis running. It skips all integration-style tests and only runs unit-level logic.