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:
-race enables the Go race detector. -count=1 disables test caching so every run is fresh.
make test-short maps to:
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.