Loading...
Loading...
Compare original and translation side by side
bash scripts/setup-test-env.shSUPABASE_TEST_URLSUPABASE_TEST_ANON_KEYnpm install --save-dev @supabase/supabase-js jest @types/jest
# or
pnpm add -D @supabase/supabase-js vitestbash scripts/setup-test-env.shSUPABASE_TEST_URLSUPABASE_TEST_ANON_KEYnpm install --save-dev @supabase/supabase-js jest @types/jest
# 或
pnpm add -D @supabase/supabase-js vitestbash scripts/test-database-workflow.sh# Run all database tests
supabase test db
# Run specific test file
supabase test db --file tests/database/users.test.sql# Test migration up/down
supabase db reset --linked
supabase db push
# Verify schema state
bash scripts/validate-schema.shbash scripts/test-database-workflow.sh# 运行所有数据库测试
supabase test db
# 运行指定测试文件
supabase test db --file tests/database/users.test.sql# 测试迁移的升级/回滚
supabase db reset --linked
supabase db push
# 验证模式状态
bash scripts/validate-schema.shbash scripts/test-auth-workflow.sh// See templates/auth-tests.ts for complete examples
test('authenticated users see only their data', async () => {
const { data, error } = await supabase
.from('private_notes')
.select('*');
expect(data).toHaveLength(userNoteCount);
expect(data.every(note => note.user_id === userId)).toBe(true);
});# Run session validation tests
npm test -- auth-session.test.tsbash scripts/test-auth-workflow.sh// 完整示例请查看templates/auth-tests.ts
test('已认证用户仅能查看自己的数据', async () => {
const { data, error } = await supabase
.from('private_notes')
.select('*');
expect(data).toHaveLength(userNoteCount);
expect(data.every(note => note.user_id === userId)).toBe(true);
});# 运行会话验证测试
npm test -- auth-session.test.tsbash scripts/test-ai-features.sh// See templates/vector-search-tests.ts
test('semantic search returns relevant results', async () => {
const queryEmbedding = await generateEmbedding('machine learning');
const { data } = await supabase.rpc('match_documents', {
query_embedding: queryEmbedding
match_threshold: 0.7
match_count: 5
});
expect(data.length).toBeGreaterThan(0);
expect(data[0].similarity).toBeGreaterThan(0.7);
});# Validate embedding pipeline
npm test -- embedding-workflow.test.ts# Run performance tests
bash scripts/benchmark-vector-search.sh [TABLE_NAME] [VECTOR_DIM]bash scripts/test-ai-features.sh// 示例请查看templates/vector-search-tests.ts
test('语义搜索返回相关结果', async () => {
const queryEmbedding = await generateEmbedding('machine learning');
const { data } = await supabase.rpc('match_documents', {
query_embedding: queryEmbedding
match_threshold: 0.7
match_count: 5
});
expect(data.length).toBeGreaterThan(0);
expect(data[0].similarity).toBeGreaterThan(0.7);
});# 验证嵌入向量流水线
npm test -- embedding-workflow.test.ts# 运行性能测试
bash scripts/benchmark-vector-search.sh [TABLE_NAME] [VECTOR_DIM]bash scripts/test-realtime-workflow.sh// See templates/realtime-tests.ts
test('receives real-time updates on insert', async () => {
const updates = [];
const subscription = supabase
.channel('test-channel')
.on('postgres_changes'
{ event: 'INSERT', schema: 'public', table: 'messages' }
(payload) => updates.push(payload)
)
.subscribe();
await supabase.from('messages').insert({ content: 'test' });
await waitFor(() => expect(updates).toHaveLength(1));
});# Run presence tests
npm test -- presence.test.tsbash scripts/test-realtime-workflow.sh// 示例请查看templates/realtime-tests.ts
test('接收插入操作的实时更新', async () => {
const updates = [];
const subscription = supabase
.channel('test-channel')
.on('postgres_changes'
{ event: 'INSERT', schema: 'public', table: 'messages' }
(payload) => updates.push(payload)
)
.subscribe();
await supabase.from('messages').insert({ content: 'test' });
await waitFor(() => expect(updates).toHaveLength(1));
});# 运行在线状态测试
npm test -- presence.test.tsbash scripts/run-e2e-tests.sh# Run all test suites
npm test -- --maxWorkers=4
# Run specific workflow
npm test -- workflows/document-rag.test.ts# Generate coverage report
npm test -- --coverage
# Generate HTML report
npm test -- --coverage --coverageReporters=htmlbash scripts/run-e2e-tests.sh# 运行所有测试套件
npm test -- --maxWorkers=4
# 运行指定工作流
npm test -- workflows/document-rag.test.ts# 生成覆盖率报告
npm test -- --coverage
# 生成HTML报告
npm test -- --coverage --coverageReporters=html# Copy CI config to your repo
cp templates/ci-config.yml .github/workflows/supabase-tests.ymlSUPABASE_TEST_URLSUPABASE_TEST_ANON_KEYSUPABASE_TEST_SERVICE_ROLE_KEY# 将CI配置复制到你的仓库
cp templates/ci-config.yml .github/workflows/supabase-tests.ymlSUPABASE_TEST_URLSUPABASE_TEST_ANON_KEYSUPABASE_TEST_SERVICE_ROLE_KEYbash scripts/cleanup-test-resources.sh# Reset to clean state
supabase db reset --linked
# Or use migration-based reset
bash scripts/reset-test-db.shbash scripts/cleanup-test-resources.sh# 重置为干净状态
supabase db reset --linked
# 或使用基于迁移的重置
bash scripts/reset-test-db.sh// Load test fixtures
const testData = await loadFixtures('users', 'posts', 'comments');
// Seed database
await seedDatabase(testData);
// Cleanup after tests
afterAll(async () => {
await cleanupFixtures();
});// 加载测试预制件
const testData = await loadFixtures('users', 'posts', 'comments');
// 填充数据库
await seedDatabase(testData);
// 测试后清理
afterAll(async () => {
await cleanupFixtures();
});// Create test users with factories
const user = await createTestUser({
email: 'test@example.com'
metadata: { role: 'admin' }
});
// Create related data
const posts = await createTestPosts(user.id, 5);// 使用工厂创建测试用户
const user = await createTestUser({
email: 'test@example.com'
metadata: { role: 'admin' }
});
// 创建关联数据
const posts = await createTestPosts(user.id, 5);test_test_test('authenticated user CRUD operations', async () => {
// 1. Sign up user
const { user } = await supabase.auth.signUp({
email: 'test@example.com'
password: 'test123'
});
// 2. Create resource
const { data } = await supabase
.from('notes')
.insert({ content: 'test note' })
.select()
.single();
// 3. Verify ownership
expect(data.user_id).toBe(user.id);
// 4. Update resource
await supabase
.from('notes')
.update({ content: 'updated' })
.eq('id', data.id);
// 5. Delete resource
await supabase.from('notes').delete().eq('id', data.id);
});test('已认证用户的CRUD操作', async () => {
// 1. 用户注册
const { user } = await supabase.auth.signUp({
email: 'test@example.com'
password: 'test123'
});
// 2. 创建资源
const { data } = await supabase
.from('notes')
.insert({ content: 'test note' })
.select()
.single();
// 3. 验证所有权
expect(data.user_id).toBe(user.id);
// 4. 更新资源
await supabase
.from('notes')
.update({ content: 'updated' })
.eq('id', data.id);
// 5. 删除资源
await supabase.from('notes').delete().eq('id', data.id);
});test('document RAG workflow', async () => {
// 1. Upload document
const doc = await uploadDocument('test.pdf');
// 2. Generate embeddings
const chunks = await chunkDocument(doc);
const embeddings = await generateEmbeddings(chunks);
// 3. Store in database
await supabase.from('document_chunks').insert(
chunks.map((chunk, i) => ({
content: chunk
embedding: embeddings[i]
document_id: doc.id
}))
);
// 4. Perform semantic search
const query = 'What is the main topic?';
const queryEmbedding = await generateEmbedding(query);
const { data } = await supabase.rpc('match_documents', {
query_embedding: queryEmbedding
match_count: 5
});
// 5. Verify results
expect(data.length).toBeGreaterThan(0);
expect(data[0].similarity).toBeGreaterThan(0.7);
});test('文档RAG工作流', async () => {
// 1. 上传文档
const doc = await uploadDocument('test.pdf');
// 2. 生成嵌入向量
const chunks = await chunkDocument(doc);
const embeddings = await generateEmbeddings(chunks);
// 3. 存储到数据库
await supabase.from('document_chunks').insert(
chunks.map((chunk, i) => ({
content: chunk
embedding: embeddings[i]
document_id: doc.id
}))
);
// 4. 执行语义搜索
const query = '主要主题是什么?';
const queryEmbedding = await generateEmbedding(query);
const { data } = await supabase.rpc('match_documents', {
query_embedding: queryEmbedding
match_count: 5
});
// 5. 验证结果
expect(data.length).toBeGreaterThan(0);
expect(data[0].similarity).toBeGreaterThan(0.7);
});test('multi-user realtime chat', async () => {
// 1. Create two users
const user1 = await createTestUser();
const user2 = await createTestUser();
// 2. Subscribe to messages
const user1Messages = [];
const user2Messages = [];
const sub1 = await subscribeToMessages(user1, user1Messages);
const sub2 = await subscribeToMessages(user2, user2Messages);
// 3. User 1 sends message
await sendMessage(user1, 'Hello from user 1');
// 4. Verify both users receive it
await waitFor(() => {
expect(user1Messages).toHaveLength(1);
expect(user2Messages).toHaveLength(1);
});
// 5. Cleanup subscriptions
await sub1.unsubscribe();
await sub2.unsubscribe();
});test('多用户实时聊天', async () => {
// 1. 创建两个用户
const user1 = await createTestUser();
const user2 = await createTestUser();
// 2. 订阅消息
const user1Messages = [];
const user2Messages = [];
const sub1 = await subscribeToMessages(user1, user1Messages);
const sub2 = await subscribeToMessages(user2, user2Messages);
// 3. 用户1发送消息
await sendMessage(user1, '来自用户1的问候');
// 4. 验证两个用户都收到消息
await waitFor(() => {
expect(user1Messages).toHaveLength(1);
expect(user2Messages).toHaveLength(1);
});
// 5. 清理订阅
await sub1.unsubscribe();
await sub2.unsubscribe();
});--maxWorkers--maxWorkersscripts/setup-test-env.shscripts/run-e2e-tests.shscripts/test-database-workflow.shscripts/test-auth-workflow.shscripts/test-ai-features.shscripts/test-realtime-workflow.shscripts/cleanup-test-resources.shscripts/validate-schema.shscripts/benchmark-vector-search.shscripts/reset-test-db.shtemplates/test-suite-template.tstemplates/database-tests.tstemplates/auth-tests.tstemplates/vector-search-tests.tstemplates/realtime-tests.tstemplates/ci-config.ymltemplates/jest.config.jstemplates/vitest.config.tsexamples/complete-test-workflow.mdexamples/ci-cd-integration.mdexamples/test-data-strategies.mdexamples/performance-benchmarks.mdexamples/mocking-strategies.mdscripts/setup-test-env.shscripts/run-e2e-tests.shscripts/test-database-workflow.shscripts/test-auth-workflow.shscripts/test-ai-features.shscripts/test-realtime-workflow.shscripts/cleanup-test-resources.shscripts/validate-schema.shscripts/benchmark-vector-search.shscripts/reset-test-db.shtemplates/test-suite-template.tstemplates/database-tests.tstemplates/auth-tests.tstemplates/vector-search-tests.tstemplates/realtime-tests.tstemplates/ci-config.ymltemplates/jest.config.jstemplates/vitest.config.tsexamples/complete-test-workflow.mdexamples/ci-cd-integration.mdexamples/test-data-strategies.mdexamples/performance-benchmarks.mdexamples/mocking-strategies.md