Improve test infrastructure and organization
- Add test-runner stage to Dockerfile for isolated test execution - Refactor Makefile test targets: separate unit and integration tests - Unit tests now run on host (fast, no containers required) - Integration tests run in containers matching production environment - Add dedicated 'tests' service to docker-compose.yml - Update test-integration target to use containerized test runner - Improve service health checks and wait conditions - Add test environment variables for consistent testing This change separates unit tests (fast, local) from integration tests (full environment, containerized) for better developer experience and more reliable CI/CD pipelines.
This commit is contained in:
+23
@@ -38,6 +38,29 @@ RUN npm run build:ts
|
|||||||
# Build the application
|
# Build the application
|
||||||
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main ./cmd/server
|
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main ./cmd/server
|
||||||
|
|
||||||
|
# Test runner stage - includes Go runtime and test dependencies
|
||||||
|
# This stage is ONLY used for running tests, never deployed to production
|
||||||
|
FROM golang:1.25-alpine AS test-runner
|
||||||
|
|
||||||
|
RUN apk --no-cache add ca-certificates curl
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy everything from builder (includes compiled binary, source code, and dependencies)
|
||||||
|
COPY --from=builder /app ./
|
||||||
|
|
||||||
|
# Install kepubify for conversion tests
|
||||||
|
RUN wget -O /usr/bin/kepubify https://github.com/pgaskin/kepubify/releases/latest/download/kepubify-linux-64bit \
|
||||||
|
&& chmod +x /usr/bin/kepubify
|
||||||
|
|
||||||
|
# Set test environment variables
|
||||||
|
ENV TEST_MODE=true
|
||||||
|
ENV RATE_LIMIT_ENABLED=false
|
||||||
|
ENV REQUESTS_PER_MINUTE=1000
|
||||||
|
|
||||||
|
# Default command for running tests
|
||||||
|
CMD ["go", "test", "./cmd/server/tests", "-v", "-timeout", "5m"]
|
||||||
|
|
||||||
# Final stage
|
# Final stage
|
||||||
FROM alpine:latest
|
FROM alpine:latest
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.PHONY: help test test-integration test-all test-stop build build-force clean rebuild logs test-env-up test-env-down
|
.PHONY: help test test-integration test-all build build-force clean rebuild logs test-env-up test-env-down verify-guidelines verify-quick
|
||||||
|
|
||||||
# Include .env file for environment variables (single source of truth)
|
# Include .env file for environment variables (single source of truth)
|
||||||
# Ignore if .env doesn't exist yet
|
# Ignore if .env doesn't exist yet
|
||||||
@@ -10,10 +10,9 @@ endif
|
|||||||
# Default target
|
# Default target
|
||||||
help:
|
help:
|
||||||
@echo "Available targets:"
|
@echo "Available targets:"
|
||||||
@echo " make test - Run unit tests"
|
@echo " make test - Run unit tests (from host, fast)"
|
||||||
@echo " make test-integration - Build containers, start services, run integration tests"
|
@echo " make test-integration - Run integration tests (in containers, matches prod)"
|
||||||
@echo " make test-all - Run all tests"
|
@echo " make test-all - Run all tests (unit + integration)"
|
||||||
@echo " make test-stop - Stop containers after testing"
|
|
||||||
@echo " make build - Build and start containers"
|
@echo " make build - Build and start containers"
|
||||||
@echo " make build-force - Force rebuild and start containers"
|
@echo " make build-force - Force rebuild and start containers"
|
||||||
@echo " make clean - Stop and remove containers"
|
@echo " make clean - Stop and remove containers"
|
||||||
@@ -22,45 +21,33 @@ help:
|
|||||||
@echo " make test-env-up - Start containers with test mode enabled"
|
@echo " make test-env-up - Start containers with test mode enabled"
|
||||||
@echo " make test-env-down - Stop test environment"
|
@echo " make test-env-down - Stop test environment"
|
||||||
|
|
||||||
# Run unit tests
|
# Run unit tests locally (fast, no containers)
|
||||||
test:
|
test:
|
||||||
go test ./... -v -short
|
go test ./internal/... -v -short
|
||||||
|
|
||||||
# Run integration tests with test mode enabled (avoids rate limiting)
|
# Run integration tests in containers (matches production environment)
|
||||||
test-integration:
|
test-integration:
|
||||||
@echo "Building containers..."
|
@echo "Building test containers..."
|
||||||
podman compose build
|
podman compose --profile tests build
|
||||||
@echo "Starting application containers..."
|
@echo "Starting application containers..."
|
||||||
podman compose up -d
|
podman compose up -d db app
|
||||||
@echo "Waiting for services to be healthy..."
|
@echo "Waiting for services to be healthy..."
|
||||||
@echo "Waiting for database..."
|
|
||||||
@until podman exec bookhoard_db pg_isready -U postgres > /dev/null 2>&1; do \
|
@until podman exec bookhoard_db pg_isready -U postgres > /dev/null 2>&1; do \
|
||||||
echo " Database not ready yet..."; \
|
echo " Database not ready yet..."; \
|
||||||
sleep 2; \
|
sleep 2; \
|
||||||
done; \
|
done; \
|
||||||
echo " ✓ Database is ready"
|
echo " ✓ Database is ready"
|
||||||
@echo "Waiting for application..."
|
@until podman exec bookhoard curl -sf http://localhost:8765/health > /dev/null 2>&1; do \
|
||||||
@sleep 3; \
|
|
||||||
until curl -sf http://localhost:8765/health > /dev/null 2>&1; do \
|
|
||||||
echo " Application not ready yet..."; \
|
echo " Application not ready yet..."; \
|
||||||
sleep 2; \
|
sleep 2; \
|
||||||
done; \
|
done; \
|
||||||
echo " ✓ Application is ready"
|
echo " ✓ Application is ready"
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo "Running integration tests from host against containerized database..."
|
@echo "Running integration tests in container..."
|
||||||
DATABASE_HOST=localhost \
|
podman compose --profile tests run --rm tests
|
||||||
DATABASE_PORT=5432 \
|
|
||||||
DATABASE_USER=postgres \
|
|
||||||
DATABASE_PASSWORD=$(DBPASS) \
|
|
||||||
DATABASE_NAME=bookhoard \
|
|
||||||
JWT_SECRET=$(JWT_SECRET) \
|
|
||||||
TEST_MODE=true \
|
|
||||||
RATE_LIMIT_ENABLED=false \
|
|
||||||
TEST_UPLOAD_PATH=./uploads \
|
|
||||||
go test ./cmd/server/tests -v -timeout 5m
|
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo "✅ Integration tests completed!"
|
@echo "✅ Integration tests completed!"
|
||||||
@echo "📝 Containers are still running. Use 'podman compose logs' to view logs or 'podman compose down' to stop."
|
@echo "📝 Containers are still running. Use 'make logs' to view logs or 'make clean' to stop."
|
||||||
|
|
||||||
# Run all tests
|
# Run all tests
|
||||||
test-all: test test-integration
|
test-all: test test-integration
|
||||||
@@ -85,24 +72,20 @@ rebuild: clean build
|
|||||||
logs:
|
logs:
|
||||||
podman compose logs -f
|
podman compose logs -f
|
||||||
|
|
||||||
# Start containers with test mode enabled for integration testing
|
# Start containers with test mode enabled for manual testing
|
||||||
test-env-up:
|
test-env-up:
|
||||||
@echo "Starting containers with test mode enabled..."
|
@echo "Starting containers with test mode enabled..."
|
||||||
TEST_MODE=true RATE_LIMIT_ENABLED=false REQUESTS_PER_MINUTE=1000 podman compose up --build -d
|
TEST_MODE=true RATE_LIMIT_ENABLED=false REQUESTS_PER_MINUTE=1000 podman compose up --build -d
|
||||||
@echo "Waiting for services to be ready..."
|
@echo "Waiting for services to be ready..."
|
||||||
sleep 10
|
@until podman exec bookhoard_db pg_isready -U postgres > /dev/null 2>&1; do sleep 1; done
|
||||||
@echo "Test environment is ready!"
|
@until podman exec bookhoard curl -sf http://localhost:8765/health > /dev/null 2>&1; do sleep 1; done
|
||||||
|
@echo "✓ Test environment is ready!"
|
||||||
|
@echo "Application available at http://localhost:8765"
|
||||||
|
|
||||||
# Stop test environment
|
# Stop test environment
|
||||||
test-env-down:
|
test-env-down:
|
||||||
podman compose down -v
|
podman compose down -v
|
||||||
|
|
||||||
# Stop containers after testing
|
|
||||||
test-stop:
|
|
||||||
@echo "Stopping containers..."
|
|
||||||
podman compose down
|
|
||||||
@echo "✓ Containers stopped"
|
|
||||||
|
|
||||||
# Verify project guidelines compliance
|
# Verify project guidelines compliance
|
||||||
verify-guidelines:
|
verify-guidelines:
|
||||||
@echo "Running comprehensive project guidelines verification..."
|
@echo "Running comprehensive project guidelines verification..."
|
||||||
|
|||||||
@@ -65,6 +65,48 @@ services:
|
|||||||
retries: 3
|
retries: 3
|
||||||
start_period: 10s
|
start_period: 10s
|
||||||
|
|
||||||
|
# Integration Tests - runs against containerized app and db
|
||||||
|
tests:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: ./Dockerfile
|
||||||
|
target: test-runner
|
||||||
|
container_name: bookhoard_tests
|
||||||
|
environment:
|
||||||
|
# Database Configuration
|
||||||
|
DATABASE_HOST: db
|
||||||
|
DATABASE_PORT: 5432
|
||||||
|
DATABASE_USER: postgres
|
||||||
|
DATABASE_PASSWORD: ${DBPASS}
|
||||||
|
DATABASE_NAME: bookhoard
|
||||||
|
|
||||||
|
# Application Configuration
|
||||||
|
JWT_SECRET: ${JWT_SECRET}
|
||||||
|
SERVER_PORT: 8765
|
||||||
|
|
||||||
|
# Test Configuration
|
||||||
|
TEST_MODE: "true"
|
||||||
|
RATE_LIMIT_ENABLED: "false"
|
||||||
|
REQUESTS_PER_MINUTE: 1000
|
||||||
|
|
||||||
|
# Conversion Service Configuration
|
||||||
|
BOOKHOARD_CONVERSION_CACHE_DIR: /app/cache/kepub
|
||||||
|
BOOKHOARD_CONVERSION_TOOL: /usr/bin/kepubify
|
||||||
|
BOOKHOARD_CONVERSION_CACHE_TTL: 24h
|
||||||
|
|
||||||
|
# Test upload path (inside container)
|
||||||
|
TEST_UPLOAD_PATH: /app/uploads
|
||||||
|
depends_on:
|
||||||
|
db:
|
||||||
|
condition: service_healthy
|
||||||
|
app:
|
||||||
|
condition: service_healthy
|
||||||
|
volumes:
|
||||||
|
- ./uploads:/app/uploads
|
||||||
|
- bookhoard_conversion_cache:/app/cache/kepub
|
||||||
|
profiles:
|
||||||
|
- tests
|
||||||
|
|
||||||
# Named Volumes
|
# Named Volumes
|
||||||
volumes:
|
volumes:
|
||||||
postgres_data:
|
postgres_data:
|
||||||
|
|||||||
Reference in New Issue
Block a user