Test Environments¶
wt provides per-session test environment isolation using port offsets. This allows multiple sessions to run their own test databases, servers, and services without conflicts.
The Problem¶
When running multiple Claude sessions on the same project:
- Session A starts Postgres on port 5432
- Session B tries to start Postgres on port 5432
- Port conflict!
The Solution: Port Offsets¶
Each session gets a unique port offset (1, 2, 3, ...). Sessions use this offset to calculate their ports:
| Session | Port Offset | Postgres | API Server |
|---|---|---|---|
| toast | 1 | 15432 | 13000 |
| shadow | 2 | 25432 | 23000 |
| obsidian | 3 | 35432 | 33000 |
How It Works¶
Environment Variable¶
Each session gets a PORT_OFFSET environment variable:
Docker Compose Integration¶
Your docker-compose.yml can use the offset:
services:
postgres:
image: postgres:15
ports:
- "${PORT_OFFSET:-0}5432:5432"
environment:
POSTGRES_DB: myapp_test
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
When PORT_OFFSET=1, Postgres maps to port 15432.
Application Configuration¶
Configure your app to use the offset:
# .env.test
DATABASE_URL=postgres://localhost:${PORT_OFFSET}5432/myapp_test
API_PORT=${PORT_OFFSET}3000
Project Configuration¶
Configure test environments in your project config:
{
"test_env": {
"setup": "docker compose up -d",
"teardown": "docker compose down",
"port_env": "PORT_OFFSET",
"health_check": "curl -sf http://localhost:${PORT_OFFSET}3000/health"
}
}
Options¶
| Field | Description |
|---|---|
setup |
Command to start test services |
teardown |
Command to stop test services |
port_env |
Environment variable name for port offset |
health_check |
Command to verify services are ready |
Lifecycle¶
On Session Create¶
- Assign next available port offset
- Export
PORT_OFFSETenvironment variable - Run setup command (
docker compose up -d) - Wait for health check to pass
- Launch Claude Code
On Session Close¶
- Run teardown command (
docker compose down) - Release port offset for reuse
Example Setup¶
docker-compose.yml¶
version: '3.8'
services:
postgres:
image: postgres:15
ports:
- "${PORT_OFFSET:-0}5432:5432"
environment:
POSTGRES_DB: myapp_test
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
redis:
image: redis:7
ports:
- "${PORT_OFFSET:-0}6379:6379"
api:
build: .
ports:
- "${PORT_OFFSET:-0}3000:3000"
environment:
DATABASE_URL: postgres://postgres:postgres@postgres:5432/myapp_test
REDIS_URL: redis://redis:6379
depends_on:
- postgres
- redis
Project Config¶
{
"name": "myproject",
"test_env": {
"setup": "docker compose up -d --wait",
"teardown": "docker compose down -v",
"health_check": "docker compose exec -T api curl -sf localhost:3000/health"
}
}
Manual Port Management¶
Check a session's port offset:
Calculate your ports:
# Pattern: ${PORT_OFFSET}<base_port>
# Postgres: ${PORT_OFFSET}5432 → 15432, 25432, 35432, ...
# Redis: ${PORT_OFFSET}6379 → 16379, 26379, 36379, ...
# API: ${PORT_OFFSET}3000 → 13000, 23000, 33000, ...
Hooks¶
Run additional commands on session lifecycle: