SvelteKit运行时设置环境变量:Playwright测试数据库配置失效问题
问题:Playwright测试中让SvelteKit应用使用动态创建的数据库
我在为SvelteKit应用运行Playwright测试时,需要为每个测试套件创建新数据库。在测试设置文件中设置了环境变量,但测试仍使用.env文件中的数据库URL。
我的设置文件代码:
// e2e/global.setup.ts import { exec as baseExec } from 'child_process'; import util from 'util'; import { test as setup } from '@playwright/test'; import { uid } from 'uid'; const exec = util.promisify(baseExec); setup('create new database', async ({}) => { // Vite replaces dot notation // https://github.com/vitejs/vite/issues/3176 // eslint-disable-next-line @typescript-eslint/dot-notation process.env['DATABASE_URL'] = `file:e2e/${uid()}.db`; await exec('npm run db:push -- --force'); });
数据库配置代码:
// src/lib/server/db/index.ts import { createClient } from '@libsql/client'; import { drizzle } from 'drizzle-orm/libsql'; import { env } from '$env/dynamic/private'; if (env.DATABASE_URL == null) { throw new Error('DATABASE_URL is not set'); } const client = createClient({ url: env.DATABASE_URL }); export const db = drizzle({ client, casing: 'snake_case' });
解决方案
问题出在Playwright的globalSetup运行在独立进程中,设置的process.env不会自动传递给SvelteKit应用进程。需要通过Playwright配置显式传递环境变量,确保应用能读取到动态生成的数据库URL。
步骤1:修改全局设置文件,生成数据库URL
在global.setup.ts中明确生成数据库URL并设置当前进程环境变量,供db:push命令使用:
// e2e/global.setup.ts import { exec as baseExec } from 'child_process'; import util from 'util'; import { test as setup } from '@playwright/test'; import { uid } from 'uid'; const exec = util.promisify(baseExec); setup('create new database', async ({}) => { const dbUrl = `file:e2e/${uid()}.db`; process.env['DATABASE_URL'] = dbUrl; await exec('npm run db:push -- --force'); });
步骤2:配置Playwright传递环境变量
修改playwright.config.ts,在use配置中将动态生成的DATABASE_URL注入到SvelteKit应用进程的环境中:
// playwright.config.ts import { defineConfig, devices } from '@playwright/test'; import { sveltekit } from '@sveltejs/kit/testing'; export default defineConfig({ testDir: './e2e', globalSetup: './e2e/global.setup.ts', use: { ...sveltekit(), // 将全局setup中设置的数据库URL传递给应用 env: { DATABASE_URL: process.env.DATABASE_URL } }, projects: [ { name: 'chromium', use: { ...devices['Desktop Chrome'] }, }, // 其他浏览器测试项目... ] });
步骤3:添加全局清理(可选)
创建global.teardown.ts清理测试生成的数据库文件,避免冗余文件堆积:
// e2e/global.teardown.ts import fs from 'fs/promises'; import path from 'path'; export default async function teardown() { const e2eDir = path.join(process.cwd(), 'e2e'); const files = await fs.readdir(e2eDir); // 删除所有e2e目录下的.db文件 for (const file of files) { if (file.endsWith('.db')) { await fs.unlink(path.join(e2eDir, file)); } } }
然后在playwright.config.ts中添加配置:globalTeardown: './e2e/global.teardown.ts'。
原理说明
SvelteKit的$env/dynamic/private会在服务器运行时读取进程环境变量,通过Playwright的use.env配置,我们将动态生成的数据库URL注入到应用进程中,确保数据库配置能正确指向测试专用的数据库。
内容的提问来源于stack exchange,提问作者Eva
相关产品推荐
相关产品推荐

