managing-database-tests
Test database testing including fixtures, transactions, and rollback management. Use when performing specialized testing. Trigger with phrases like "test the database", "run database tests", or "validate data integrity".
What this skill does
# Database Test Manager
## Overview
Manage database testing including fixture loading, transaction-based test isolation, migration validation, query performance testing, and data integrity checks. Supports PostgreSQL, MySQL, MongoDB, SQLite (in-memory), and Redis with ORM-agnostic patterns for Prisma, TypeORM, SQLAlchemy, Knex, and Drizzle.
## Prerequisites
- Database instance available for testing (Docker container, in-memory SQLite, or dedicated test server)
- Database client library and ORM installed (Prisma, TypeORM, Knex, SQLAlchemy, etc.)
- Migration files up to date and tested independently
- Test database connection string configured in environment (distinct from development/production)
- Database seed data scripts for baseline test state
## Instructions
1. Set up the test database infrastructure:
- Use Docker to spin up a dedicated test database: `docker run -d -p 5433:5432 --name test-db postgres:16-alpine`.
- Or use SQLite in-memory mode for fast unit tests: `sqlite::memory:`.
- Or use Testcontainers for ephemeral database per test suite.
- Verify the test database is isolated from development data.
2. Run database migrations against the test database:
- Execute `npx prisma migrate deploy` or `npx knex migrate:latest --env test`.
- Verify all migrations apply cleanly to an empty database.
- Test rollback: run `migrate:rollback` and verify schema reverts correctly.
3. Implement test isolation strategy (choose one):
- **Transaction rollback**: Wrap each test in a transaction; roll back after assertions. Fastest option.
- **Truncation**: Truncate all tables in `beforeEach`. Simpler but slower.
- **Database recreation**: Drop and recreate the database before each test suite. Slowest, most thorough.
4. Create database fixture utilities:
- Factory functions that insert records and return the created entity with its database-generated ID.
- Seed functions for standard test scenarios (empty state, populated state, edge cases).
- Cleanup utilities that handle foreign key ordering for truncation.
5. Write database-specific test cases:
- **CRUD operations**: Insert, query, update, delete records and verify database state.
- **Constraint validation**: Attempt invalid inserts (null on NOT NULL, duplicate on UNIQUE) and verify rejection.
- **Referential integrity**: Verify cascading deletes, foreign key enforcement, and orphan prevention.
- **Index performance**: Verify queries use expected indexes with EXPLAIN ANALYZE.
- **Transaction isolation**: Test concurrent updates and verify conflict handling.
6. Test database query performance:
- Run `EXPLAIN ANALYZE` on critical queries and assert expected index usage.
- Benchmark query execution time with representative data volumes.
- Flag queries doing sequential scans on large tables.
7. Validate migration safety:
- Test each migration can run on a populated database without data loss.
- Verify backward compatibility (old code works with new schema during rollout).
- Check migration execution time is acceptable for production deployment.
## Output
- Database test files organized by entity in `tests/database/` or `tests/models/`
- Fixture and factory utility files in `tests/helpers/` or `tests/factories/`
- Migration test scripts validating up/down migrations
- Query performance benchmarks with EXPLAIN ANALYZE output
- Test database Docker Compose configuration
## Error Handling
| Error | Cause | Solution |
|-------|-------|---------|
| Foreign key constraint violation during cleanup | Truncation order does not respect foreign key dependencies | Truncate tables in reverse dependency order; or disable FK checks during cleanup (`SET CONSTRAINTS ALL DEFERRED`) |
| Connection pool exhausted | Too many test workers opening separate connections | Use a single shared connection for tests; limit pool size; close connections in `afterAll` |
| Migration fails on test database | Schema drift between development and test databases | Drop and recreate test database; run all migrations from scratch; verify migration checksums |
| Transaction rollback does not clean up | ORM auto-commits or test creates a new connection outside the transaction | Inject the transaction connection into all ORM operations; disable auto-commit in test config |
| Slow test suite due to database I/O | Too many INSERT/DELETE operations per test | Use in-memory SQLite for unit tests; batch seed data; use transaction rollback instead of truncation |
## Examples
**Jest with Prisma transaction rollback:**
```typescript
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
describe('UserRepository', () => {
afterAll(async () => { await prisma.$disconnect(); });
it('creates and retrieves a user', async () => {
await prisma.$transaction(async (tx) => {
const created = await tx.user.create({
data: { name: 'Alice', email: '[email protected]' },
});
const found = await tx.user.findUnique({ where: { id: created.id } });
expect(found).toMatchObject({ name: 'Alice', email: '[email protected]' });
// Transaction rolls back automatically when we throw
throw new Error('ROLLBACK');
}).catch((e) => {
if (e.message !== 'ROLLBACK') throw e;
});
});
});
```
**pytest with database fixture and rollback:**
```python
import pytest
from sqlalchemy import create_engine
from sqlalchemy.orm import Session
@pytest.fixture
def db_session():
engine = create_engine("postgresql://test:test@localhost:5433/testdb") # 5433 = configured value
connection = engine.connect()
transaction = connection.begin()
session = Session(bind=connection)
yield session
session.close()
transaction.rollback()
connection.close()
def test_insert_and_query_user(db_session):
db_session.execute(
text("INSERT INTO users (name, email) VALUES (:n, :e)"),
{"n": "Alice", "e": "[email protected]"}
)
result = db_session.execute(text("SELECT name FROM users WHERE email = :e"),
{"e": "[email protected]"}).fetchone()
assert result[0] == "Alice"
```
**Migration validation test:**
```typescript
describe('Database Migrations', () => {
it('applies all migrations to empty database', async () => {
const result = await exec('npx prisma migrate deploy');
expect(result.exitCode).toBe(0);
});
it('migration is idempotent', async () => {
await exec('npx prisma migrate deploy');
const result = await exec('npx prisma migrate deploy');
expect(result.exitCode).toBe(0); // Second run should succeed (no-op)
});
});
```
## Resources
- Prisma testing guide: https://www.prisma.io/docs/guides/testing
- SQLAlchemy testing patterns: https://docs.sqlalchemy.org/en/20/orm/session_transaction.html
- Testcontainers databases:
- Knex migrations: https://knexjs.org/guide/migrations.html
- PostgreSQL EXPLAIN ANALYZE: https://www.postgresql.org/docs/current/using-explain.html
Related in Code Review
gstack
IncludedFast headless browser for QA testing and site dogfooding. Navigate pages, interact with elements, verify state, diff before/after, take annotated screenshots, test responsive layouts, forms, uploads, dialogs, and capture bug evidence. Use when asked to open or test a site, verify a deployment, dogfood a user flow, or file a bug with screenshots. (gstack)
startup-due-diligence
IncludedLegal due diligence review for seed-stage and Series A startups (US, Delaware C-Corp focus). Supports both investor and founder perspectives. Capabilities include: (1) Interactive document review and issue spotting; (2) Document request list generation; (3) Cap table and SAFE/convertible note analysis; (4) Red flag identification with severity ratings; (5) Diligence report generation. TRIGGERS: due diligence, DD, startup investment, cap table review, Series A, seed round, investor diligence, legal review startup, SAFE analysis, convertible note, 409A, founder vesting.
interview-master
IncludedThis skill should be used when the user asks to "generate interview questions", "prepare for interview", "optimize resume", "conduct mock interview", "analyze git commits for resume", "generate resume from code", "review my resume", or mentions interview preparation, career assistance, or extracting project experience from git history. Provides comprehensive interview and career development guidance for both job seekers and interviewers.
fix-issue
IncludedFixes GitHub issues using parallel analysis agents for root cause investigation, code exploration, and regression detection. Reads issue context from gh CLI, searches codebase and memory for related patterns, generates a fix with tests, and links the resolution back to the issue via PR. Includes prevention analysis to avoid recurrence. Use when debugging errors, resolving regressions, fixing bugs, or triaging issues.
sf-apex
IncludedGenerates and reviews Salesforce Apex code with 150-point scoring. TRIGGER when: user writes, reviews, or fixes Apex classes, triggers, test classes, batch/queueable/schedulable jobs, or touches .cls/.trigger files. DO NOT TRIGGER when: LWC JavaScript (use sf-lwc), Flow XML (use sf-flow), SOQL-only queries (use sf-soql), or non-Salesforce code.
swift-development
IncludedComprehensive Swift development for building, testing, and deploying iOS/macOS applications. Use when Claude needs to: (1) Build Swift packages or Xcode projects from command line, (2) Run tests with XCTest or Swift Testing framework, (3) Manage iOS simulators with simctl, (4) Handle code signing, provisioning profiles, and app distribution, (5) Format or lint Swift code with SwiftFormat/SwiftLint, (6) Work with Swift Package Manager (SPM), (7) Implement Swift 6 concurrency patterns (async/await, actors, Sendable), (8) Create SwiftUI views with MVVM architecture, (9) Set up Core Data or SwiftData persistence, or any other Swift/iOS/macOS development tasks.