RSpec "An error occurred in a before(:suite) hook"
A global before(:suite) hook raised before any example ran. Because it sets up the whole run - DB connection, schema, fixtures - its failure aborts the entire suite, not a single spec.
What this error means
RSpec prints "An error occurred in a before(:suite) hook" with the underlying exception, and few or no examples run. The error is in setup (often DB/migration), not in the tests themselves.
An error occurred in a `before(:suite)` hook.
Failure/Error: ActiveRecord::Base.connection.execute(...)
PG::ConnectionBad:
could not connect to server: Connection refused
Is the server running on host "localhost" (127.0.0.1) and accepting
TCP/IP connections on port 5432?Common causes
Test database unavailable
The before(:suite) connects to or migrates the test DB. If the Postgres/MySQL service is not up (or not ready) in CI, the hook raises and the suite aborts.
Pending migrations or missing schema
Setup that loads the schema or checks for pending migrations fails when the test DB was never prepared (db:test:prepare).
How to fix it
Start and wait for the database service
Bring up the DB as a CI service and prepare the test schema before RSpec.
# .github/workflows/ci.yml
services:
postgres:
image: postgres:16
ports: ['5432:5432']
options: >-
--health-cmd pg_isready --health-interval 10s --health-retries 5
# then, before rspec:
# bin/rails db:test:prepareMake setup resilient and explicit
- Wait for the DB to accept connections (health check) before running specs.
- Run
db:test:prepare(ordb:schema:load) so the schema exists. - Read the wrapped exception - the real cause is printed under the hook message.
How to prevent it
- Define the DB as a CI service with a health check.
- Prepare the test schema in a dedicated step before RSpec.
- Keep global setup minimal and fail with a clear message.