@iodome/prisma
v0.4.1
Published
<img width="84" height="78" alt="iodome-logo-3" src="https://github.com/user-attachments/assets/69aacbd2-6305-4fac-a842-22637d8b0439" />
Readme
@iodome/prisma
Prisma utilities for complete test data isolation support for Postgres in Playwright and Vitest. Ensures each test runs with a fresh, isolated database state to prevent test interference and flaky tests.
Installation
npm install --save-dev @iodome/prisma
# or
pnpm add -D @iodome/prisma
# or
yarn add -D @iodome/prismaFeatures
- 🔒 Complete test isolation - Each test runs in its own database state
- ⚡ Fast execution - Template databases for Playwright, transactions for Vitest
- 🔄 Automatic cleanup - No manual database cleanup needed
- 🏃 Parallel testing - Run tests in parallel without conflicts
- 🛠️ Easy integration - Works with your existing Prisma setup
Usage
Playwright (E2E Testing)
1. Create test fixtures
// tests/fixtures.ts
import { PrismaClient } from "@prisma/client";
import { createTestFixtures } from "@iodome/prisma/playwright";
export const test = createTestFixtures(PrismaClient);2. Set up global hooks
// global.setup.ts
import { createTemplateDatabase } from "@iodome/prisma/playwright";
export default async function globalSetup() {
// Create a template database for faster test initialization
await createTemplateDatabase();
}// global.teardown.ts
import { dropDatabases } from "@iodome/prisma/playwright";
export default async function globalTeardown() {
// Clean up all test databases
await dropDatabases();
}3. Configure Playwright
// playwright.config.ts
export default defineConfig({
globalSetup: "./tests/e2e/global.setup.ts", // path to setup file
globalTeardown: "./tests/e2e/global.teardown.ts", // path to teardown file
// ...
});4. Write tests
// tests/example.spec.ts
import { test } from "./fixtures";
import { expect } from "@playwright/testing";
test("create and verify user", async ({ page, prisma }) => {
// Create test data with isolated Prisma client pointing
// to an unique database per test
const user = await prisma.user.create({
data: {
name: "Test User",
email: "[email protected]",
},
});
// Test your application
await page.goto("/users");
await expect(page.getByText(user.name)).toBeVisible();
});Vitest (Unit/Integration Testing)
1. Set up test isolation
// vitest.setup.ts
import prisma from "@/prisma/db";
import { wrapTestsInTransactions } from "@iodome/prisma/vitest";
wrapTestsInTransactions(prisma);
/* wraps tests in transactions using
beforeEach, afterEach from vitest /*2. Configure Vitest
// vitest.config.ts
export default defineConfig({
test: {
setupFiles: ["./vitest.setup.ts"],
// ... other config
},
});3. Write tests
// tests/actions/articles.test.ts
import prisma from "@/prisma/db";
import { describe, it, expect } from "vitest";
import { getComments } from "../actions/articles";
describe("getComments", () => {
it("returns comments for an article in descending order", async () => {
const article = await prisma.article.create({
data: {
title: "title",
content: "content",
},
});
const firstComment = await prisma.comment.create({
data: {
content: "first comment",
articleId: article.id,
authorId: user.id,
},
}); // ... secondComment, thirdComment
const comments = await getComments(article.id);
expect(comments).toStrictEqual([thirdComment, secondComment, firstComment]);
});
});How It Works
Playwright Mode
- Creates a separate PostgreSQL database for each test (pattern:
iodome_test_[testId]) - Uses a template database for fast initialization
- Automatically starts a test server with isolated database
- Cleans up databases after tests complete
Vitest Mode
- Wraps each test in a PostgreSQL transaction
- Automatically rolls back all changes after each test
- Much faster than creating separate databases
- Perfect for unit and integration tests
Configuration
Environment Variables
DATABASE_URL- PostgreSQL connection string (required for Playwright)IODOME_DEBUG- Enable query loggingCIorIODOME_BUILD- Use production server command instead of dev - better for running large amounts of tests.
Database Requirements
- PostgreSQL (tested with versions 12+)
- Default connection:
postgres://postgres:postgres@localhost:5432
API Reference
Playwright
createTestFixtures(PrismaClientConstructor)
Creates Playwright test fixtures with an isolated database.
Returns: Extended test object with fixtures:
prisma- Isolated PrismaClient instance pointing to your isolated databasebaseURL- URL of the test server- All standard Playwright fixtures (page, context, etc.)
createTemplateDatabase()
Creates a template database for faster test initialization. Call in global setup.
dropDatabases()
Removes all test databases. Call in global teardown.
Vitest
wrapTestsInTransactions(prismaClient)
Enables transaction-based test isolation. Call once in setup file.
Parameters:
prismaClient- Your configured PrismaClient instance
Best Practices
- Playwright: Always use global setup/teardown for template database management
- Vitest: Call
wrapTestsInTransactions()once in your setup file - Performance: Use template databases for Playwright tests with complex schemas
Troubleshooting
Tests are slow
- For Playwright: Ensure you're using
createTemplateDatabase()in global setup - For Vitest: Verify transactions are enabled with
wrapTestsInTransactions()
Database not found errors
- Check your PostgreSQL server is running
- Ensure your PostgreSQL user has CREATE DATABASE permissions
Tests are flaking
- This is more likely to happen when running large amounts of tests using playwright. Using a production-like server (i.e.
next start) instead of a dev server (i.e.next dev) is much more reliable and will use far less resources on your machine. The tradeoff is that you'll have to run your build (i.e.next build) before running your test.
I have found that using dev servers is faster for test-driven development where I'm rerunning a single test, and using production servers is better when running my test suite locally or in CI. Due to the amount of resources used by spinning up a lot of dev servers in parallel, flakiness becomes more of an issue.
Using production servers on my local machine, I was able to run 600 playwright tests across 12 workers with consistent success. This will vary from machine to machine.
License
MIT © Michael (fundefined)
