Files
hnh-map/docs/testing.md
Nikolay Tatarinov a3a4c0e896 Enhance development workflow with Docker integration
- 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.
2026-03-04 11:39:27 +03:00

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() and bbolt.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).