| name | better-auth-test-utils |
| description | Use when writing integration or E2E tests for apps using Better Auth. Covers the testUtils plugin for creating test users, authenticated sessions, cookie injection for Playwright/Puppeteer, OTP capture, database helpers, and test fixtures. Trigger on "test utils," "test helpers," "getCookies," "test factory," "mock auth," "test session," "OTP capture," "authenticated test," "e2e auth setup," "integration test auth," "Playwright cookies," or "test user factory." For auth configuration, see better-auth-best-practices. For security hardening, see better-auth-security-best-practices. |
Better Auth Test Utils
Testing utilities for integration and E2E testing against Better Auth. Provides factories, database helpers, authenticated session creation, and OTP capture.
This plugin is for test environments only. Never use in production.
Quick Start
import { betterAuth } from "better-auth"
import { testUtils } from "better-auth/plugins"
export const auth = betterAuth({
plugins: [testUtils()]
})
const ctx = await auth.$context
const test = ctx.test
Activity-Based Reference Guide
API Surface
Factories (no database writes)
| Method | Returns | Notes |
|---|
test.createUser(overrides?) | User object | Defaults: random email, "Test User", emailVerified: true |
test.createOrganization(overrides?) | Organization object | Requires organization plugin |
Database Helpers (persist/delete)
| Method | Returns | Notes |
|---|
test.saveUser(user) | Saved user | Writes to database |
test.deleteUser(userId) | void | Removes user and related data |
test.saveOrganization(org) | Saved org | Requires organization plugin |
test.deleteOrganization(orgId) | void | Requires organization plugin |
test.addMember({ userId, organizationId, role }) | Member | Requires organization plugin |
Auth Helpers (session creation)
| Method | Returns | Notes |
|---|
test.login({ userId }) | { session, user, headers, cookies, token } | Full session with all formats |
test.getAuthHeaders({ userId }) | Headers object | For fetch/Request usage |
test.getCookies({ userId, domain? }) | Cookie array | Playwright/Puppeteer compatible |
OTP Capture (requires captureOTP: true)
| Method | Returns | Notes |
|---|
test.getOTP(identifier) | OTP string | By email or phone |
test.clearOTPs() | void | Reset captured OTPs between tests |
Decision Tree
What kind of test are you writing?
│
├─ Integration test (no browser)?
│ ├─ Need authenticated API calls → auth-helpers.md, vitest-integration.md
│ ├─ Need test data → factories.md, database-helpers.md
│ └─ Testing OTP flows → otp-capture.md
│
├─ E2E test (Playwright)?
│ ├─ Need authenticated pages → playwright-integration.md (getCookies + addCookies)
│ ├─ Testing login/signup UI → auth-helpers.md (setup only, test UI directly)
│ ├─ Testing OTP verification UI → otp-capture.md, playwright-integration.md
│ └─ Need reusable auth fixture → common-patterns.md
│
└─ Setting up test infrastructure?
├─ First time setup → setup.md
├─ Creating Playwright fixtures → common-patterns.md
└─ Organizing test data → factories.md, database-helpers.md
Critical Patterns
Playwright: Skip Login UI for Feature Tests
test("dashboard test", async ({ page }) => {
await page.goto("/login");
await page.fill("[name=email]", "test@example.com");
});
test("dashboard test", async ({ context, page }) => {
const cookies = await testUtils.getCookies({ userId: user.id, domain: "localhost" });
await context.addCookies(cookies);
await page.goto("/dashboard");
});
Test Isolation
test("feature test", async ({ context, page }) => {
const user = testUtils.createUser({ email: `test-${Date.now()}@example.com` });
await testUtils.saveUser(user);
try {
const cookies = await testUtils.getCookies({ userId: user.id });
await context.addCookies(cookies);
} finally {
await testUtils.deleteUser(user.id);
}
});
Related Skills
better-auth-best-practices — Auth server/client configuration
better-auth-security-best-practices — Rate limiting, CSRF, secrets
playwright-best-practices — Test structure, locators, assertions
dogfood-test-pipeline — Exploratory testing → Playwright test generation