Local service testing
Opinionated GitHub-native development workflow with 28 skills for autonomous, issue-driven software development with Claude Code
npx -y skills add troykelly/claude-skills --skill local-service-testingAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 11 stars11 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Use when code changes touch database, cache, queue, or other service-dependent components - enforces testing against real local services instead of mocks
SKILL.md
8.1 KB, ~1.9k tokens by cl100k_base, as published. Nobody here has run it
Local Service Testing
Overview
Test against real services locally before pushing. CI validates—it doesn't discover.
Core principle: If you mock what you can run locally, you're hiding bugs.
Announce at start: "I'm using local-service-testing to verify changes against real services."
The Iron Law
CI DISCOVERS NOTHING.
IF CI FINDS A BUG, YOUR LOCAL TESTING FAILED.
Local services exist for a reason. Use them.
Critical Clarification
Unit tests with mocks: REQUIRED (for TDD cycle) Integration tests with real services: ALSO REQUIRED
This skill does NOT replace mocking in unit tests. It ADDS the requirement for integration tests against real services. Both are mandatory.
When This Skill Applies
| Code Change | Required Service | Must Test Against |
|---|---|---|
| Database models/entities | postgres | Real postgres |
| Migrations | postgres | Real postgres |
| Repository/ORM layer | postgres | Real postgres |
| SQL queries | postgres | Real postgres |
| Cache operations | redis | Real redis |
| Session storage | redis | Real redis |
| Pub/sub messages | redis/rabbitmq | Real queue |
| Queue workers | redis/rabbitmq | Real queue |
| API endpoints | all services | All running |
If your change touches any of these, you MUST test against the real service.
Service Detection
At session start, the session-start.sh hook reports available services:
Checking development services...
✓ Found docker-compose.yml
Available services:
✓ postgres (running)
○ redis (not running)
Tip: Start services with: docker-compose up -d
Starting Services
# Start all services
docker-compose up -d
# Start specific service
docker-compose up -d postgres
# Check status
docker-compose ps
Service Connection Strings
| Service | Default Connection |
|---|---|
| postgres | postgresql://localhost:5432/dev |
| redis | redis://localhost:6379 |
| rabbitmq | amqp://localhost:5672 |
Check your project's .env.example or docker-compose.yml for actual values.
Testing Protocol
Step 1: Identify Service Dependencies
Before testing, identify which services your changes require:
# Check what files you've changed
git diff --name-only HEAD~1
# Map to services:
# *.sql, *migration*, *model*, *entity*, *repository* → postgres
# *cache*, *redis*, *session*, *queue*, *pub*, *sub* → redis
# *worker*, *job*, *consumer* → queue service
Step 2: Ensure Services Running
# Start required services
docker-compose up -d postgres redis
# Verify they're ready
docker-compose ps
# Test connectivity
# Postgres
psql postgresql://localhost:5432/dev -c "SELECT 1"
# Redis
redis-cli ping
Step 3: Run Integration Tests
# Run integration tests (not unit tests with mocks)
pnpm test:integration
# Or run specific integration test suite
pnpm test --grep "integration"
# For Python projects
pytest tests/integration/
# For Go projects
go test -tags=integration ./...
Step 4: Verify Locally Before Pushing
Before git push:
# Full verification
pnpm build
pnpm lint
pnpm typecheck
pnpm test # Unit tests
pnpm test:integration # Integration tests against real services
Two-Layer Testing Requirement
Both Are Required
| Test Layer | Purpose | Uses Mocks? | Uses Real Services? | Required? |
|---|---|---|---|---|
| Unit tests | TDD cycle, verify logic | YES | No | YES |
| Integration tests | Verify real behavior | No | YES | YES |
Why Both?
- Unit tests with mocks: Fast, enable RED-GREEN-REFACTOR, isolate logic
- Integration tests with services: Catch real-world failures mocks miss
We've experienced 80% failure rates with ORM migrations because unit tests with mocks passed but real databases rejected the changes.
What Mocks Miss
// Mock says this works
const mockDb = {
query: jest.fn().mockResolvedValue([{ id: 1 }])
};
// But real postgres throws:
// ERROR: relation "users" does not exist
// ERROR: column "email" cannot be null
// ERROR: duplicate key violates unique constraint
Real services reveal:
- Schema mismatches
- Constraint violations
- Connection issues
- Transaction behavior
- Performance problems
Artifact Requirement
Before creating a PR, you must post local testing evidence to the issue.
Required Artifact Format
<!-- LOCAL-TESTING:START -->
## Local Service Testing
| Service | Status | Verification |
|---------|--------|--------------|
| postgres | ✅ Running | Migrations applied, queries executed |
| redis | ✅ Running | Cache operations verified |
**Tests Run:**
- `pnpm test:integration` - PASSED
- Manual verification of [specific feature]
**Tested At:** 2025-01-15T10:30:00Z
<!-- LOCAL-TESTING:END -->
Where to Post
Post as a comment on the GitHub issue you're working on. This is checked by the validate-local-testing.sh PreToolUse hook before PR creation.
When Artifact is Required
The hook checks:
- Does docker-compose.yml exist?
- Do changed files match service patterns?
- If yes to both → artifact required
If no services are relevant to your changes, no artifact is needed.
Common Patterns
Database Testing
// GOOD: Test against real postgres
describe('UserRepository (integration)', () => {
beforeAll(async () => {
await db.migrate.latest();
});
afterAll(async () => {
await db.destroy();
});
it('creates user with unique email constraint', async () => {
await userRepo.create({ email: '[email protected]' });
// Real postgres will throw on duplicate
await expect(
userRepo.create({ email: '[email protected]' })
).rejects.toThrow(/unique constraint/);
});
});
Cache Testing
// GOOD: Test against real redis
describe('CacheService (integration)', () => {
beforeEach(async () => {
await redis.flushdb();
});
it('expires keys after TTL', async () => {
await cache.set('key', 'value', { ttl: 1 });
expect(await cache.get('key')).toBe('value');
await sleep(1100);
expect(await cache.get('key')).toBeNull();
});
});
API Testing
// GOOD: Test against real services
describe('POST /users (integration)', () => {
it('creates user and caches result', async () => {
const response = await request(app)
.post('/users')
.send({ email: '[email protected]' });
expect(response.status).toBe(201);
// Verify in real database
const user = await db('users').where({ email: '[email protected]' }).first();
expect(user).toBeDefined();
// Verify in real cache
const cached = await redis.get(`user:${user.id}`);
expect(cached).toBeDefined();
});
});
Troubleshooting
| Problem | Solution |
|---|---|
| Service not starting | Check docker-compose logs [service] |
| Connection refused | Ensure service is running and port is correct |
| Database doesn't exist | Run migrations: pnpm migrate |
| Tests pass locally, fail in CI | Environment variable mismatch—check .env vs CI config |
| Flaky integration tests | Check for proper test isolation and cleanup |
Checklist
Before creating PR:
- Identified all service dependencies for changes
- All required services are running locally
- Integration tests pass against real services
- Posted local testing artifact to issue
- Did not rely on mocks for service-dependent code
Integration
This skill is called by:
tdd-full-coverage- For integration testing requirementsissue-driven-development- Before PR creationverification-before-merge- As a merge gate
This skill is enforced by:
validate-local-testing.sh- PreToolUse hook blocks PR without artifact
This skill references:
environment-bootstrap- For service startup patternssession-start- For service detection at session start
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.