From harness-claude
Provides patterns for writing integration tests with real databases, test containers, and API endpoints using Prisma, PostgreSQL, and supertest.
How this skill is triggered — by the user, by Claude, or both
Slash command
/harness-claude:test-integration-patternsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> Write integration tests that exercise real dependencies using test databases and containers
Write integration tests that exercise real dependencies using test databases and containers
// test/setup.ts
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient({
datasources: { db: { url: process.env.TEST_DATABASE_URL } },
});
beforeEach(async () => {
// Clean tables in dependency order
await prisma.post.deleteMany();
await prisma.user.deleteMany();
});
afterAll(async () => {
await prisma.$disconnect();
});
export { prisma };
import { PostgreSqlContainer, StartedPostgreSqlContainer } from '@testcontainers/postgresql';
let container: StartedPostgreSqlContainer;
beforeAll(async () => {
container = await new PostgreSqlContainer().start();
process.env.DATABASE_URL = container.getConnectionUri();
// Run migrations
await execSync('npx prisma migrate deploy');
}, 60_000); // Container startup timeout
afterAll(async () => {
await container.stop();
});
import request from 'supertest';
import { app } from '../app';
describe('POST /api/users', () => {
it('creates a user and returns 201', async () => {
const response = await request(app)
.post('/api/users')
.send({ name: 'Alice', email: '[email protected]' })
.expect(201);
expect(response.body).toMatchObject({
name: 'Alice',
email: '[email protected]',
});
expect(response.body.id).toBeDefined();
});
it('returns 400 for invalid email', async () => {
await request(app).post('/api/users').send({ name: 'Alice', email: 'invalid' }).expect(400);
});
});
import { prisma } from './setup';
let tx: PrismaClient;
beforeEach(async () => {
// Start a transaction for test isolation
// Each test sees a clean state without deleting data
await prisma.$executeRaw`BEGIN`;
});
afterEach(async () => {
await prisma.$executeRaw`ROLLBACK`;
});
describe('OrderService', () => {
it('creates order and deducts inventory', async () => {
// Arrange — seed test data
const product = await prisma.product.create({
data: { name: 'Widget', stock: 10, price: 9.99 },
});
const service = new OrderService(prisma);
// Act
const order = await service.createOrder({
items: [{ productId: product.id, quantity: 3 }],
userId: testUser.id,
});
// Assert — verify both order creation AND inventory deduction
expect(order.total).toBe(29.97);
const updatedProduct = await prisma.product.findUnique({
where: { id: product.id },
});
expect(updatedProduct!.stock).toBe(7);
});
});
async function createTestUser(overrides?: Partial<User>) {
return prisma.user.create({
data: {
email: `test-${crypto.randomUUID()}@test.com`,
name: 'Test User',
...overrides,
},
});
}
// vitest.config.integration.ts
export default defineConfig({
test: {
include: ['**/*.integration.test.ts'],
setupFiles: ['./test/integration-setup.ts'],
testTimeout: 30_000,
hookTimeout: 60_000,
},
});
Run with: vitest --config vitest.config.integration.ts
Integration tests verify that multiple components work together correctly. They catch issues that unit tests miss — serialization bugs, query errors, constraint violations, and middleware ordering problems.
Test database strategies:
Data isolation approaches:
deleteMany in reverse dependency orderIntegration vs E2E: Integration tests exercise the backend (service + database) without a browser. E2E tests include the full stack (browser + backend + database). Integration tests are faster and more focused.
Trade-offs:
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeSets up integration tests across databases, APIs, and message queues using Testcontainers, with DB seeding, cleanup strategies, and Docker dependencies.
Executes integration tests for APIs, databases, services, queues, and files using real dependencies and Docker infra. Validates component interactions without mocks.
Guides writing integration tests that verify component interactions (database, API, message bus) with real dependencies. Covers contract testing as a lighter alternative for service boundaries.