Skip to main content
Luca Brunner·

Testcontainers Postgres, factories, transaction-per-test cleanup - my whole harness in one go

Creates integration test suites with test containers, database setup, API client fixtures, and realistic test data factories.

Integration Test Suite Scaffold

You are a QA engineer building an integration test suite for a backend service. Create complete, runnable tests. ## Service Under Test - Service: {{service_name}} - Language: {{programming_language}} - Framework: {{framework}} - Database: {{database}} - External dependencies: {{external_deps}} (e.g., Redis, S3, third-party APIs) - Test framework: {{test_framework}} ## API Endpoints to Test ``` {{endpoints_spec}} ``` ## Integration Test Requirements Generate: 1. **Test Configuration** - Test database setup, environment config, Docker Compose for deps 2. **Test Fixtures** - Factory functions for creating test data (users, orders, etc.) 3. **Database Setup** - Migration runner, seed data, transaction-per-test cleanup 4. **Test Client** - Authenticated HTTP client wrapper with helper methods 5. **Happy Path Tests** - Complete user journeys across multiple endpoints 6. **Error Integration Tests** - Database failures, network timeouts, 3rd party errors 7. **Auth Tests** - Token expiry, invalid tokens, role-based access 8. **Database Assertion Tests** - Verify state changes after API calls 9. **Event/Queue Tests** - Verify async jobs triggered correctly 10. **Performance Smoke Tests** - Response time assertions (< 200ms typical) Use test containers if applicable. Ensure tests are parallelizable. Include proper cleanup in teardown.

Ergebnisse

Integration suite for `order-service` (TypeScript + Express, Postgres, Stripe) using Vitest + Testcontainers. Transaction-per-test rollback keeps cases isolated and parallelizable. ```typescript // test/setup.ts — real Postgres in a container, migrated once import { PostgreSqlContainer } from "@testcontainers/postgresql"; let pg: Awaited<ReturnType<PostgreSqlContainer["start"]>>; beforeAll(async () => { pg = await new PostgreSqlContainer("postgres:16-alpine").start(); process.env.DATABASE_URL = pg.getConnectionUri(); await runMigrations(); }); afterAll(() => pg.stop()); // factory export const makeUser = (over = {}) => ({ email: `u${Date.now()}@test.io`, plan: "pro", ...over, }); ``` ```typescript // test/orders.spec.ts it("creates an order and persists it", async () => { const user = await seed(makeUser()); const res = await client.as(user).post("/orders", { sku: "SKU-001", qty: 1 }); expect(res.status).toBe(201); expect(res.time).toBeLessThan(200); // smoke perf assertion const row = await db.query("SELECT status FROM orders WHERE id=$1", [res.body.id]); expect(row.status).toBe("pending"); // DB-state assertion }); ``` Stripe is stubbed via a WireMock container; each test runs inside a `BEGIN ... ROLLBACK` so no cleanup script is needed.

Modell: Claude Sonnet 4

23 Likes9 SavesScore: 18

1 Kommentar

Lena Fischer·

Okay this code generation output just saved me an afternoon.