Skip to content

feat(db): add --use-shadow-db flag to test db command#4871

Open
lightstrike wants to merge 1 commit intosupabase:developfrom
lightstrikelabs:lightstrikelabs/feat/test-with-shadow-db
Open

feat(db): add --use-shadow-db flag to test db command#4871
lightstrike wants to merge 1 commit intosupabase:developfrom
lightstrikelabs:lightstrikelabs/feat/test-with-shadow-db

Conversation

@lightstrike
Copy link

Runs pgTAP tests against an ephemeral shadow database built from migrations, keeping the local dev database untouched. Reuses the existing CreateShadowDatabase/MigrateShadowDatabase machinery from db diff. Uses host networking so pg_prove can reach the shadow container via 127.0.0.1:<shadow_port>.

What kind of change does this PR introduce?

Feature — adds a new --use-shadow-db flag to both supabase db test and supabase test db.

What is the current behavior?

supabase db test (and supabase test db) always runs pgTAP tests against the local development database. This means:

  • Tests that write data or alter schema pollute the dev environment.
  • There is no built-in way to run tests against a clean, migration-derived database.
  • Developers must manually reset their local DB after destructive test runs.

What is the new behavior?

When --use-shadow-db is passed, the CLI:

  1. Spins up an ephemeral shadow container via CreateShadowDatabase (same machinery used by db diff).
  2. Applies all migrations with MigrateShadowDatabase.
  3. Overrides the pg_prove connection to point at the shadow container using host networking (127.0.0.1:<shadow_port>).
  4. Runs pgTAP tests against the shadow database.
  5. Tears down the shadow container when finished (via defer DockerRemove).

The local dev database is never touched.

Files changed (5):

  • cmd/db.go — flag wiring on dbTestCmd
  • cmd/test.go — mirror flag on testDbCmd
  • internal/db/test/test.go — shadow DB lifecycle + host networking
  • internal/db/test/test_test.go — updated call sites with false param
  • pkg/config/templates/config.toml — updated shadow_port doc comment

Additional context

Prior art: ephemeral test databases in other frameworks

Using a dedicated, disposable database for test runs is a well-established pattern across mature frameworks:

Framework Approach
Django Automatically creates a test_<dbname> database, applies all migrations, runs tests inside transactions for per-test isolation, and destroys the DB afterward (docs).
Rails Maintains a permanent test environment with its own database defined in database.yml. The schema is loaded from db/schema.rb (or structure.sql) before each test run, and each test is wrapped in a transaction that rolls back (guide).
Laravel Supports SQLite :memory: databases or a dedicated MySQL/Postgres test DB. The RefreshDatabase trait migrates or transaction-wraps each test automatically (docs).
Prisma Has an explicit shadow database concept — a temporary DB created/destroyed during prisma migrate dev to detect schema drift and validate migrations. For integration tests, Prisma recommends Docker-based ephemeral databases (docs).

The --use-shadow-db flag brings the Supabase CLI in line with this industry-standard practice: tests run against a clean, ephemeral database built from migrations, leaving development data untouched.

Why a flag (not the default)?

The flag is opt-in to ensure safe backwards compatibility — existing workflows that expect tests to run against the local dev database continue to work unchanged. Once the shadow DB path has been validated in real-world usage and deemed stable, we recommend making it the default behavior (with an opt-out flag if needed).

Runs pgTAP tests against an ephemeral shadow database built from
migrations, keeping the local dev database untouched. Reuses the
existing CreateShadowDatabase/MigrateShadowDatabase machinery from
db diff. Uses host networking so pg_prove can reach the shadow
container via 127.0.0.1:<shadow_port>.
@lightstrike lightstrike requested a review from a team as a code owner February 19, 2026 01:28
@coderabbitai
Copy link

coderabbitai bot commented Feb 19, 2026

No actionable comments were generated in the recent review. 🎉


📝 Walkthrough

Summary by CodeRabbit

Release Notes

  • New Features

    • Added --use-shadow-db flag to run tests with a temporary isolated database, enabling safer test execution without affecting the main database.
  • Documentation

    • Updated configuration documentation to clarify shadow database support in test commands.

Walkthrough

This PR introduces support for running database tests against a temporary shadow database. A new --use-shadow-db flag is added to the test command that, when enabled, creates a temporary database from migrations, executes tests in isolation against this shadow database, and cleans up the temporary instance afterward. The test runner function signature is updated to accept the shadow database flag as a parameter, and the implementation coordinates the lifecycle of the shadow database including creation, migration, health checking, and cleanup.

Sequence Diagram

sequenceDiagram
    participant CLI as Test CLI Command
    participant Runner as test.Run()
    participant Diff as diff Module
    participant Start as start Module
    participant Docker as Docker/Container
    participant DB as Shadow Database

    CLI->>Runner: Run(ctx, args, config, useShadowDb=true, fs)
    
    alt useShadowDb enabled
        Runner->>Diff: CreateShadowDatabase()
        Diff->>Docker: Create container from image
        Docker->>DB: Initialize database
        Diff-->>Runner: Shadow DB created
        
        Runner->>Start: WaitForHealthyService()
        Start->>DB: Health check
        DB-->>Start: Service healthy
        Start-->>Runner: Ready
        
        Runner->>Diff: MigrateShadowDatabase()
        Diff->>DB: Apply migrations
        DB-->>Diff: Migrations applied
        Diff-->>Runner: Migrations complete
        
        Runner->>Runner: Override config (host, port, user, password, database)
        Runner->>Runner: Run tests against shadow DB
        
        Runner->>Docker: Defer DockerRemove
        Docker->>DB: Remove container
        DB-->>Docker: Cleaned up
    else useShadowDb disabled
        Runner->>Runner: Run tests against configured DB
    end
    
    Runner-->>CLI: Tests complete
Loading

Comment @coderabbitai help to get the list of available commands and usage tips.

@coveralls
Copy link

Pull Request Test Coverage Report for Build 22164831089

Details

  • 5 of 32 (15.63%) changed or added relevant lines in 3 files are covered.
  • 6 unchanged lines in 2 files lost coverage.
  • Overall coverage decreased (-0.1%) to 61.651%

Changes Missing Coverage Covered Lines Changed/Added Lines %
cmd/test.go 0 1 0.0%
cmd/db.go 0 3 0.0%
internal/db/test/test.go 5 28 17.86%
Files with Coverage Reduction New Missed Lines %
cmd/db.go 1 0.0%
internal/utils/git.go 5 57.14%
Totals Coverage Status
Change from base Build 22142437948: -0.1%
Covered Lines: 7707
Relevant Lines: 12501

💛 - Coveralls

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments