transact-rs/sqlx · error
failed to apply test fixture {:?}: {:?}
Error message
failed to apply test fixture {:?}: {:?} What it means
sqlx-core's testing scaffold (setup_test_db, used by #[sqlx::test]) panics when executing a fixture SQL file against the freshly created test database fails. The panic wraps the sqlx error from `conn.execute(fixture.contents)`, printing the fixture path and the underlying DB error, so the real cause (bad SQL, dependency order, missing schema) is in the attached error value.
Source
Thrown at sqlx-core/src/testing/mod.rs:269
for<'c> &'c mut DB::Connection: Executor<'c, Database = DB>,
{
let mut conn = copts
.connect()
.await
.expect("failed to connect to test database");
if let Some(migrator) = args.migrator {
migrator
.run_direct(None, &mut conn, false)
.await
.expect("failed to apply migrations");
}
for fixture in args.fixtures {
(&mut conn)
.execute(fixture.contents)
.await
.unwrap_or_else(|e| panic!("failed to apply test fixture {:?}: {:?}", fixture.path, e));
}
conn.close()
.await
.expect("failed to close setup connection");
}
View on GitHub (pinned to 03af8bcc57)
Solutions
- Read the wrapped error in the panic message — it names the exact SQL error (relation does not exist, constraint violation, syntax).
- Ensure all prerequisite fixtures are listed, dependencies first: `fixtures(path("schema.sql"), path("users.sql"))`.
- Run migrations before fixtures (the test scaffold applies migrations if configured; otherwise execute them in a setup step).
- Validate the fixture SQL directly: pipe it into a fresh `psql`/`mysql`/`sqlite3` empty database to reproduce outside of tests.
- Make fixtures idempotent and self-contained (CREATE TABLE IF NOT EXISTS / ON CONFLICT DO NOTHING).
Example fix
// before
#[sqlx::test(fixtures(path("orders.sql")))]
async fn test_orders(pool: PgPool) { /* orders.sql references users table */ }
// after
#[sqlx::test(fixtures(path("schema.sql"), path("users.sql"), path("orders.sql")))]
async fn test_orders(pool: PgPool) { /* prerequisites loaded first */ } Defensive patterns
Strategy: validation
Validate before calling
// Validate fixture SQL against a scratch DB before running tests:
// psql "postgres://localhost/scratch" -v ON_ERROR_STOP=1 -f tests/fixtures/orders.sql
// Also list fixtures in dependency order:
// #[sqlx::test(fixtures(path("schema.sql"), path("users.sql"), path("orders.sql")))] Try / catch
// The panic already embeds the underlying error; parse it in test output: // failed to apply test fixture "tests/fixtures/orders.sql": <sqlx error> — // read the wrapped sqlx::Error to find the failing SQL statement.
Prevention
- Keep each fixture self-contained or list prerequisites first
- Run migrations before fixtures in test setup
- Validate fixture SQL in CI against an empty database
- Use IF NOT EXISTS / ON CONFLICT to make fixtures idempotent
When it happens
Trigger: `#[sqlx::test(fixtures(path("users.sql")))]` where users.sql contains SQL that errors on the empty test database: referencing a table created by another fixture that isn't listed, syntax errors, DB-specific SQL, INSERTs violating constraints, or fixtures executed in the wrong order.
Common situations: Fixture files that worked locally against a manually-seeded dev DB but assume objects a clean test DB lacks; fixture ordering issues (fixtures run in listed order but dependencies not listed first); migrations not applied before fixtures in the test setup.
Related errors
- failed to apply migrations
- failed to close setup connection
- cleanup_test() invoked outside `#[sqlx::test]`
- DATABASE_URL must be set
- failed to parse DATABASE_URL
AI-assisted analysis of transact-rs/sqlx@03af8bcc57 (2026-09-03).
Data as JSON: /api/errors/6e2122ff1ba4ec7b.
Report an issue: GitHub.