Make integration-test migration replay fail closed
If an integration test cannot create its schema but continues into entity tests, the delayed failures lose the original cause. A missing migration directory, zero SQL files, a read error, or one failed statement is a bo…
Table of contents
If an integration test cannot create its schema but continues into entity tests, the delayed failures lose the original cause. A missing migration directory, zero SQL files, a read error, or one failed statement is a bootstrap failure.
Replay without a false green
Require the SSOT directory and at least one SQL file.
Sort files and decode them as UTF-8.
Stop and roll back the transaction on the first SQL error.
Start entity tests only after probing representative tables, columns, and constraints.
Safe replay rules
- Throw immediately when the repository SSOT directory cannot be found.
- Do not treat a directory with no SQL files as success.
- Read sorted SQL files as UTF-8 and stop at the first execution error.
- Apply the same rule to seeds; an applied-count log is not proof of success.
This contract distinguishes “the test ran” from “the test ran against the real schema.” Migration idempotency is a separate concern; the test harness must first refuse to hide failure.
Bootstrap state table
| Input state | Unsafe handling | Safe handling |
|---|---|---|
| Directory missing | Continue with an empty list | Fail with the path |
| Zero SQL files | Report zero applied as success | Fail as configuration error |
| UTF-8 read failure | Skip the file | Stop with the filename |
| Third SQL fails | Continue with the first two | Roll back the transaction |
| Seed fails | Discover it in entity tests | Fail during bootstrap |
path → non-empty SQL list → sort → UTF-8 read → transaction replay → schema probe
└────────── any failure prevents entity tests from starting ──────────┘
The final probe checks representative tables, columns, and constraints rather than an applied count. It catches false greens caused by reading the wrong directory or a driver ignoring part of a script.
Questions for the verdict
Check that migration files were actually read, that the first SQL error remains attached to its cause, and that an applied-count log is not being treated as proof of success.
Related course: Close partial failure, recovery, and platform boundaries
Terms in this content
More in quality
All in this category →Related posts
Idempotent migrations and partial-failure recovery
An operational database cannot be changed in one shot like a fresh database. Preserve existing rows, converge to the same state on repeated runs, and expose enough failure context for a safe retry.
TypeORM and read-only entities
TypeORM was once a representative ORM in the Node camp and was widely used alongside NestJS. Its position has shifted somewhat as new ORMs appeared, but it still runs in many codebases.
SSOT Everywhere
SSOT (Single Source of Truth) started as a data governance term and has expanded into a principle for code, documentation, and schema operations. This article covers the origin, areas of application, and trade-offs.
SQL as the single source of truth
Where should the schema's truth live? ORM models, migration files, DDL SQL — there are several candidates. We compare the cumulative-migration model with the single-SQL-file + CREATE IF NOT EXISTS model.