Testing database logic with Drizzle ORM requires real Postgres—not mocks. But you shouldn't sacrifice type safety or deal with manual cleanup.
In this lesson, you'll set up drizzle-orm-test to test your Drizzle ORM queries with ephemeral Postgres databases. Get automatic context management, type safety, and transaction-based test isolation.
Why drizzle-orm-test?
drizzle-orm-test is a drop-in replacement for pgsql-test that patches Drizzle's client to automatically apply context before each query. This makes RLS testing seamless while maintaining Drizzle's type-safe query builder.
Prerequisites
Ensure Postgres is running and database users are initialized as shown in prerequisites.
Install pgpm
Create a Workspace for Your Drizzle Project
Create a pgpm workspace to organize your Drizzle project:
When prompted, enter your workspace name:
Install dependencies:
Create a Module for Your Database
Create a pgpm module to organize your database code:
Enter module details when prompted:
Navigate to the module:
Install Drizzle Testing Dependencies
Install Drizzle ORM and drizzle-orm-test in your module:
The drizzle-orm-test package is built on top of pgsql-test with Drizzle support baked in. It automatically patches Drizzle's client to apply context before each query, making RLS testing seamless.
Defining Your Schema
Create src/schema.ts:
Adding the Database Change
Add the pets table as a database change:
Edit deploy/pets_table.sql:
Your First Drizzle Test
Inside of __tests__/drizzle-basic.test.ts:
Run the test:
Note: If you experience connection issues, see Tests fail to connect to database.
You should see:
What just happened? The drizzle(pg.client) pattern creates a Drizzle instance using the patched client from drizzle-orm-test. All queries automatically include context (which we'll use for RLS in the next lesson).
Note that we're using pg from getConnections(), which represents the superuser connection. The db connection (also available from getConnections()) represents the app user and will be featured in the next lesson for RLS testing. Both are PgTestClient instances with the same methods.
Understanding the Pattern
The key pattern is:
This gives you:
- Type-safe queries with Drizzle's query builder
- Automatic context management for RLS (applied before each query)
- Transaction isolation via
beforeEach()/afterEach() - Standard Drizzle API - no wrapper needed
Using Drizzle's Query Builder
Test more advanced queries:
What You've Accomplished
You now have a complete Drizzle testing environment:
- pgpm workspace organized for your database project
- Drizzle ORM configured with type-safe schema definitions
drizzle-orm-testconfigured for instant, isolated test databases- Database changes tracked with pgpm migrations
- Working tests that demonstrate type-safe queries and transaction isolation
Key Takeaways
- drizzle-orm-test is a drop-in replacement for pgsql-test with Drizzle support
- Use
drizzle(pg.client)to create a Drizzle instance with context management pgvsdbconnections: Both arePgTestClientinstances with the same methods.pgis the superuser connection (used in this lesson), whiledbis the app user connection that can toggle roles withsetContext()for RLS testing (featured in the next lesson)- Type-safe queries ensure compile-time correctness
- Transaction isolation keeps tests clean and fast
- Standard Drizzle API works without modification
- No wrapper needed - just use Drizzle normally
What's Next
In the next lesson, we'll add Row-Level Security (RLS) policies and test them with Drizzle by switching between user contexts.
RLS testing is where drizzle-orm-test really shines—the automatic context management means you can test security policies with the same Drizzle queries you use in production.
