- Updated CONTRIBUTING.md to clarify the use of Makefile targets for running tasks inside Docker, eliminating the need for local Go or Node installations. - Introduced docker-compose.tools.yml for backend and frontend tools, allowing for streamlined testing, linting, and formatting. - Created Dockerfile.tools to set up a Go environment with necessary tools for testing and linting. - Modified Makefile to include separate targets for backend and frontend tests, improving clarity and usability. - Updated documentation in development.md and testing.md to reflect the new Docker-based workflow for running tests and development tasks.
3.6 KiB
Testing
Running tests
The canonical way to run tests is via Docker (no local Go or Node required):
make test
This runs both backend and frontend tests in Docker. For one side only:
make test-backend # Go tests only
make test-frontend # Vitest only
Backend (Go)
With Docker (recommended): make test-backend or make test.
Or directly if you have Go installed:
go test ./...
Frontend (Vitest)
With Docker (recommended): make test-frontend or make test.
Or directly if you have Node installed:
cd frontend-nuxt
npm test
The frontend uses Vitest with happy-dom as the test environment. Configuration is in frontend-nuxt/vitest.config.ts.
Test structure
Backend
Tests use the standard testing package with table-driven tests. Each test creates a temporary bbolt database via t.TempDir() so tests are fully isolated and require no external dependencies.
| File | What it covers |
|---|---|
internal/app/app_test.go |
Domain types (Coord.Name, Coord.Parent, Auths.Has), Topic pub/sub |
internal/app/migrations_test.go |
Migration on fresh DB, idempotency, version tracking |
internal/app/store/db_test.go |
All store CRUD operations (users, sessions, tokens, config, maps, grids, tiles, markers, OAuth states), context cancellation, edge cases |
internal/app/services/auth_test.go |
Login, session management, token validation, password changes, OAuth bootstrap |
internal/app/services/admin_test.go |
User CRUD, settings, map management, wipe |
internal/app/services/map_test.go |
Map data retrieval, characters, markers, tiles, config, grid storage, SSE watchers |
internal/app/services/client_test.go |
Content-type fix helper |
internal/app/handlers/handlers_test.go |
HTTP integration tests for all API endpoints using httptest (auth, admin, map data, error handling) |
Frontend
Frontend tests are located alongside the source code in __tests__/ directories:
| File | What it covers |
|---|---|
frontend-nuxt/composables/__tests__/useMapApi.test.ts |
Map API composable |
frontend-nuxt/composables/__tests__/useMapLogic.test.ts |
Map logic composable |
frontend-nuxt/composables/__tests__/useAppPaths.test.ts |
Application path helpers |
frontend-nuxt/lib/__tests__/Character.test.ts |
Character lib |
frontend-nuxt/lib/__tests__/Marker.test.ts |
Marker lib |
frontend-nuxt/lib/__tests__/UniqueList.test.ts |
UniqueList utility |
Nuxt auto-imports are mocked via frontend-nuxt/__mocks__/nuxt-imports.ts and the #imports alias in the Vitest config.
Writing new tests
Backend conventions
- Use table-driven tests where multiple input/output pairs make sense.
- Create a temporary database with
t.TempDir()andbbolt.Open()for isolation. - Use
t.Helper()in test helper functions. - Use
t.Cleanup()to close the database after the test.
Example pattern:
func TestMyFeature(t *testing.T) {
dir := t.TempDir()
db, err := bbolt.Open(filepath.Join(dir, "test.db"), 0600, nil)
if err != nil {
t.Fatal(err)
}
t.Cleanup(func() { db.Close() })
st := store.New(db)
// ... test logic ...
}
For handler tests, use httptest.NewRecorder() and httptest.NewRequest() to simulate HTTP requests without starting a real server.
Frontend conventions
- Place tests in
__tests__/directories next to the source files. - Name test files
<source-name>.test.ts. - Use Vitest globals (
describe,it,expect).