From harness-claude
Conducts service boundary testing, API contract verification, and consumer-driven contract validation for microservices without full end-to-end infrastructure.
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeThis skill uses the workspace's default tool permissions.
> Service boundary testing, API contract verification, and consumer-driven contract validation. Ensures services communicate correctly without requiring full end-to-end infrastructure.
Executes integration tests for APIs, databases, services, queues, and files using real dependencies and Docker infra. Validates component interactions without mocks.
Checks and configures integration testing infrastructure for services, databases, and external dependencies using Supertest, pytest, or Testcontainers in JS/TS, Python, Rust, Go projects.
Sets up integration tests across databases, APIs, and message queues using Testcontainers, with DB seeding, cleanup strategies, and Docker dependencies.
Share bugs, ideas, or general feedback.
Service boundary testing, API contract verification, and consumer-driven contract validation. Ensures services communicate correctly without requiring full end-to-end infrastructure.
Identify service boundaries. Scan the project structure for:
Map inter-service dependencies. For each service, catalog:
Inventory existing integration tests. Glob for test files in tests/integration/, __integration__/, tests/api/, and contract-tests/. Classify by type:
Identify coverage gaps. Cross-reference discovered endpoints and service boundaries against existing tests. Flag untested:
Select test strategy. Based on the architecture:
Set up test database. Choose the appropriate strategy:
Configure mock services for external dependencies. For each upstream dependency:
Set up contract broker (if using Pact). Configure:
Create test fixtures and seed data. Generate:
Verify mock infrastructure starts. Run a smoke test that:
Write API endpoint tests. For each endpoint, test:
Write consumer-driven contract tests (when applicable). For each consumer-provider pair:
Write repository/data access tests. For each data access layer:
Write error handling and resilience tests. Verify:
Organize tests by execution speed. Tag or separate:
Run the full integration test suite. Execute all tests with verbose output. Collect:
Verify contract compliance. If using Pact:
Validate test isolation. Run tests in random order (if the framework supports it). Any test that fails only when run after a specific other test has a shared-state bug. Fix immediately.
Run harness validate. Confirm the project passes all harness checks including the new integration test infrastructure.
Generate coverage report. Summarize:
If a knowledge graph exists at .harness/graph/, refresh it after code changes to keep graph queries accurate:
harness scan [path]
harness validate -- Run in VALIDATE phase after all integration tests are implemented. Confirms project-wide health.harness check-deps -- Run after MOCK phase to verify test infrastructure dependencies do not leak into production bundles.emit_interaction -- Used at checkpoints to present contract verification results and coverage gaps to the human.harness validate passes with the integration test suite in placeDISCOVER output:
Framework: Express 4.18 with TypeScript
Database: PostgreSQL via Prisma
Endpoints: 14 routes across 4 controllers (users, projects, tasks, auth)
Existing tests: 3 integration tests in tests/integration/ (auth only)
Coverage gaps: projects CRUD, tasks filtering, user profile update
IMPLEMENT -- API endpoint test with supertest:
// tests/integration/projects.test.ts
import request from 'supertest';
import { app } from '../../src/app';
import { prisma } from '../../src/db';
import { createTestUser, generateAuthToken } from '../helpers/auth';
describe('POST /api/projects', () => {
let authToken: string;
beforeAll(async () => {
const user = await createTestUser(prisma);
authToken = generateAuthToken(user.id);
});
afterAll(async () => {
await prisma.project.deleteMany();
await prisma.user.deleteMany();
});
it('creates a project with valid data', async () => {
const response = await request(app)
.post('/api/projects')
.set('Authorization', `Bearer ${authToken}`)
.send({ name: 'Test Project', description: 'Integration test' });
expect(response.status).toBe(201);
expect(response.body).toMatchObject({
name: 'Test Project',
description: 'Integration test',
});
expect(response.body.id).toBeDefined();
});
it('returns 400 when name is missing', async () => {
const response = await request(app)
.post('/api/projects')
.set('Authorization', `Bearer ${authToken}`)
.send({ description: 'No name' });
expect(response.status).toBe(400);
expect(response.body.errors).toContainEqual(expect.objectContaining({ field: 'name' }));
});
it('returns 401 without auth token', async () => {
const response = await request(app).post('/api/projects').send({ name: 'Unauthorized' });
expect(response.status).toBe(401);
});
});
IMPLEMENT -- Consumer side (frontend):
// contract-tests/consumer/project-service.pact.ts
import { PactV3, MatchersV3 } from '@pact-foundation/pact';
import { ProjectClient } from '../../src/clients/project-client';
const { like, eachLike, uuid } = MatchersV3;
const provider = new PactV3({
consumer: 'Dashboard',
provider: 'ProjectService',
});
describe('ProjectService contract', () => {
it('returns a list of projects', async () => {
await provider
.given('projects exist for user')
.uponReceiving('a request for user projects')
.withRequest({
method: 'GET',
path: '/api/projects',
headers: { Authorization: like('Bearer token-123') },
})
.willRespondWith({
status: 200,
body: eachLike({
id: uuid(),
name: like('Project Alpha'),
createdAt: like('2026-01-15T10:30:00Z'),
}),
})
.executeTest(async (mockServer) => {
const client = new ProjectClient(mockServer.url);
const projects = await client.listProjects('token-123');
expect(projects).toHaveLength(1);
expect(projects[0].name).toBe('Project Alpha');
});
});
});
| Rationalization | Why It Is Wrong |
|---|---|
| "Testing the happy path is sufficient -- error scenarios are edge cases" | The success criteria require error scenarios (400, 401, 403, 404, 500, timeout) for all public endpoints. Error paths are where real-world failures happen. |
| "We can test against the staging environment instead of setting up local mocks" | No integration tests that require external staging environments for CI. Tests must run with local test doubles. |
| "The consumer contract changed, so I will update the consumer test to match the provider" | Contract changes must be coordinated. The provider may have introduced a bug, not an intentional change. |
| "Tests pass when I run them in order, so they are fine" | Phase 4 requires running tests in random order. Any test that fails only in a specific order has a shared-state bug. |