Skip to content
Back to skills

Database Testing

ASecurity

Exercise data-access code, migrations, and transactions against the real database engine so constraints, rollbacks, and schema changes are proven rather than assumed. Use when tests for queries or migrations run on SQLite while production runs Postgres.

  • 7 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 5, 2026
ai-agentssqldockertestingapidatabase

Works with

  • api

Security analysis

A100/100

Scanned September 5, 2026

npx -y skills add Amey-Thakur/AI-SKILLS --skill database-testing --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Database Testing?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Database Testing
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/amey-thakur-database-testing/badge)](https://www.skillsdirectory.com/skills/amey-thakur-database-testing)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: database-testing
description: Exercise data-access code, migrations, and transactions against the real database engine so constraints, rollbacks, and schema changes are proven rather than assumed. Use when tests for queries or migrations run on SQLite while production runs Postgres.
---

# Database testing

Data code fails on the specifics an ORM hides: the dialect a query compiles
to, the constraint that fires on a duplicate, the migration that locks a
table under load. A test against SQLite when production runs Postgres proves
your mock of the database, not the database. Run against the real engine and
the surprises show up in CI instead of at 3 a.m.

## Method

1. **Run against the production engine and version.** Start Postgres 16 (or
   whatever prod runs) with Testcontainers or a docker-compose fixture, not
   SQLite. Dialect differences in JSON operators, upserts, and case sensitivity
   are exactly where the bugs are.
2. **Test migrations both directions.** Apply the up migration to an empty
   schema, assert the tables and indexes exist, then apply the down and assert
   it returns clean. A down migration nobody runs is a rollback that fails
   during an incident.
3. **Isolate each test in a transaction and roll back.** Open a transaction in
   setup, run the test, roll back in teardown. This keeps tests
   order-independent and fast, and no test sees rows another one wrote.
4. **Prove the constraints fire.** Insert a duplicate against a unique index,
   an orphan against a foreign key, a null into a NOT NULL column, and assert
   the IntegrityError. A constraint no test triggers is a comment, not a
   guarantee.
5. **Verify rollback on partial failure.** Drive a multi-statement unit of work
   that errors midway and assert nothing persisted. An application-level
   transaction that leaves half its writes behind is the classic
   data-corruption bug.
6. **Test concurrency where the code relies on it.** For `SELECT FOR UPDATE`,
   optimistic version columns, or a chosen isolation level, run two concurrent
   transactions and assert the serialization failure or the correct winner, not
   just the single-threaded path.

## Checks

- Do the tests run on the same engine and major version as production?
- Does a broken migration or a violated constraint fail a test rather than pass
  silently?
- After a mid-transaction error, does an assertion confirm zero rows landed?

## Boundaries

This is the persistence layer under your code. The HTTP surface above it
belongs to api-testing, cross-service seams to integration-testing, and the
shape of the schema itself to schema-design. Reuse the project's fixture and
container setup instead of standing up a parallel one.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…