diff --git a/backend/test-api.js b/backend/test-api.js deleted file mode 100644 index 61bde28..0000000 --- a/backend/test-api.js +++ /dev/null @@ -1,314 +0,0 @@ -import http from 'http' - -const BASE_URL = 'http://localhost:3001' - -// 测试结果收集 -const testResults = { - passed: 0, - failed: 0, - tests: [] -} - -// HTTP请求辅助函数 -function request(method, path, data = null) { - return new Promise((resolve, reject) => { - const url = new URL(path, BASE_URL) - const options = { - method, - headers: { - 'Content-Type': 'application/json' - } - } - - const req = http.request(url, options, (res) => { - let body = '' - res.on('data', (chunk) => { body += chunk }) - res.on('end', () => { - try { - const response = JSON.parse(body) - resolve({ status: res.statusCode, data: response }) - } catch (e) { - resolve({ status: res.statusCode, data: body }) - } - }) - }) - - req.on('error', reject) - - if (data) { - req.write(JSON.stringify(data)) - } - req.end() - }) -} - -// 断言函数 -function assert(condition, testName, message = '') { - const result = { - name: testName, - passed: condition, - message: message || (condition ? '通过' : '失败') - } - testResults.tests.push(result) - if (condition) { - testResults.passed++ - console.log(`✅ ${testName}`) - } else { - testResults.failed++ - console.log(`❌ ${testName}: ${message}`) - } -} - -// 检查响应格式 -function checkResponseFormat(response, testNamePrefix) { - assert( - response.data.hasOwnProperty('success'), - `${testNamePrefix} - 响应包含success字段`, - `响应缺少success字段,实际响应: ${JSON.stringify(response.data)}` - ) - assert( - response.data.hasOwnProperty('data'), - `${testNamePrefix} - 响应包含data字段`, - `响应缺少data字段,实际响应: ${JSON.stringify(response.data)}` - ) - assert( - response.data.hasOwnProperty('message'), - `${testNamePrefix} - 响应包含message字段`, - `响应缺少message字段,实际响应: ${JSON.stringify(response.data)}` - ) -} - -// 主测试流程 -async function runTests() { - console.log('='.repeat(60)) - console.log('个人理财系统 - API集成测试') - console.log('='.repeat(60)) - - try { - // 1. 健康检查 - console.log('\n【1】健康检查测试') - console.log('-'.repeat(40)) - const healthRes = await request('GET', '/health') - assert(healthRes.status === 200, '健康检查状态码200') - checkResponseFormat(healthRes, '健康检查') - assert(healthRes.data.success === true, '健康检查success为true') - - // 2. 基础API信息 - console.log('\n【2】API基础信息测试') - console.log('-'.repeat(40)) - const apiRes = await request('GET', '/api') - assert(apiRes.status === 200, 'API信息状态码200') - checkResponseFormat(apiRes, 'API信息') - - // 3. 用户接口测试 - console.log('\n【3】用户接口测试') - console.log('-'.repeat(40)) - - // 创建测试用户 - const createUserRes = await request('POST', '/api/users', { - name: '测试用户', - email: 'test' + Date.now() + '@example.com' - }) - assert(createUserRes.status === 200, '创建用户状态码200') - checkResponseFormat(createUserRes, '创建用户') - assert(createUserRes.data.success === true, '创建用户success为true') - assert(createUserRes.data.data !== null, '创建用户返回数据不为null') - assert(createUserRes.data.data.id !== undefined, '创建用户返回ID') - - const testUserId = createUserRes.data.data.id - - // 获取用户列表 - const getUsersRes = await request('GET', '/api/users') - assert(getUsersRes.status === 200, '获取用户列表状态码200') - checkResponseFormat(getUsersRes, '获取用户列表') - assert(Array.isArray(getUsersRes.data.data), '用户列表为数组') - - // 4. 账户接口测试 - console.log('\n【4】账户接口测试') - console.log('-'.repeat(40)) - - // 创建账户 - const createAccountRes = await request('POST', '/api/accounts', { - userId: testUserId, - name: '测试账户', - type: 'cash', - balance: 1000 - }) - assert(createAccountRes.status === 200, '创建账户状态码200') - checkResponseFormat(createAccountRes, '创建账户') - assert(createAccountRes.data.success === true, '创建账户success为true') - assert(createAccountRes.data.data !== null, '创建账户返回数据不为null') - - const testAccountId = createAccountRes.data.data.id - - // 获取账户列表 - const getAccountsRes = await request('GET', `/api/accounts?userId=${testUserId}`) - assert(getAccountsRes.status === 200, '获取账户列表状态码200') - checkResponseFormat(getAccountsRes, '获取账户列表') - assert(Array.isArray(getAccountsRes.data.data), '账户列表为数组') - - // 获取单个账户 - const getAccountRes = await request('GET', `/api/accounts/${testAccountId}`) - assert(getAccountRes.status === 200, '获取单个账户状态码200') - checkResponseFormat(getAccountRes, '获取单个账户') - assert(getAccountRes.data.data.id === testAccountId, '账户ID匹配') - - // 更新账户 - const updateAccountRes = await request('PUT', `/api/accounts/${testAccountId}`, { - name: '测试账户(已更新)', - balance: 2000 - }) - assert(updateAccountRes.status === 200, '更新账户状态码200') - checkResponseFormat(updateAccountRes, '更新账户') - assert(updateAccountRes.data.data.name === '测试账户(已更新)', '账户名称已更新') - - // 5. 交易记录接口测试 - console.log('\n【5】交易记录接口测试') - console.log('-'.repeat(40)) - - // 创建收入记录 - const createIncomeRes = await request('POST', '/api/records', { - userId: testUserId, - accountId: testAccountId, - type: 'income', - amount: 500, - category: '工资', - description: '测试收入' - }) - assert(createIncomeRes.status === 200, '创建收入记录状态码200') - checkResponseFormat(createIncomeRes, '创建收入记录') - assert(createIncomeRes.data.success === true, '创建收入记录success为true') - - const testRecordId = createIncomeRes.data.data.id - - // 创建支出记录 - const createExpenseRes = await request('POST', '/api/records', { - userId: testUserId, - accountId: testAccountId, - type: 'expense', - amount: 200, - category: '餐饮', - description: '测试支出' - }) - assert(createExpenseRes.status === 200, '创建支出记录状态码200') - checkResponseFormat(createExpenseRes, '创建支出记录') - - // 获取记录列表 - const getRecordsRes = await request('GET', `/api/records?userId=${testUserId}`) - assert(getRecordsRes.status === 200, '获取记录列表状态码200') - checkResponseFormat(getRecordsRes, '获取记录列表') - assert(Array.isArray(getRecordsRes.data.data), '记录列表为数组') - - // 获取单个记录 - const getRecordRes = await request('GET', `/api/records/${testRecordId}`) - assert(getRecordRes.status === 200, '获取单个记录状态码200') - checkResponseFormat(getRecordRes, '获取单个记录') - - // 更新记录 - const updateRecordRes = await request('PUT', `/api/records/${testRecordId}`, { - description: '测试收入(已更新)' - }) - assert(updateRecordRes.status === 200, '更新记录状态码200') - checkResponseFormat(updateRecordRes, '更新记录') - - // 6. 预算接口测试 - console.log('\n【6】预算接口测试') - console.log('-'.repeat(40)) - - const currentMonth = new Date().toISOString().slice(0, 7) - - // 创建预算 - const createBudgetRes = await request('POST', '/api/budgets', { - userId: testUserId, - category: '餐饮', - amount: 1000, - month: currentMonth - }) - assert(createBudgetRes.status === 200, '创建预算状态码200') - checkResponseFormat(createBudgetRes, '创建预算') - assert(createBudgetRes.data.success === true, '创建预算success为true') - - const testBudgetId = createBudgetRes.data.data.id - - // 获取预算列表 - const getBudgetsRes = await request('GET', `/api/budgets?userId=${testUserId}`) - assert(getBudgetsRes.status === 200, '获取预算列表状态码200') - checkResponseFormat(getBudgetsRes, '获取预算列表') - assert(Array.isArray(getBudgetsRes.data.data), '预算列表为数组') - - // 获取单个预算 - const getBudgetRes = await request('GET', `/api/budgets/${testBudgetId}`) - assert(getBudgetRes.status === 200, '获取单个预算状态码200') - checkResponseFormat(getBudgetRes, '获取单个预算') - - // 更新预算 - const updateBudgetRes = await request('PUT', `/api/budgets/${testBudgetId}`, { - amount: 1500 - }) - assert(updateBudgetRes.status === 200, '更新预算状态码200') - checkResponseFormat(updateBudgetRes, '更新预算') - - // 7. 统计接口测试 - console.log('\n【7】统计接口测试') - console.log('-'.repeat(40)) - - // 月度统计 - const monthlyStatsRes = await request('GET', `/api/statistics/monthly?userId=${testUserId}&month=${currentMonth}`) - assert(monthlyStatsRes.status === 200, '月度统计状态码200') - checkResponseFormat(monthlyStatsRes, '月度统计') - assert(monthlyStatsRes.data.data.totalIncome !== undefined, '月度统计包含总收入') - assert(monthlyStatsRes.data.data.totalExpense !== undefined, '月度统计包含总支出') - - // 趋势统计 - const trendRes = await request('GET', `/api/statistics/trend?userId=${testUserId}`) - assert(trendRes.status === 200, '趋势统计状态码200') - checkResponseFormat(trendRes, '趋势统计') - assert(Array.isArray(trendRes.data.data), '趋势统计返回数组') - - // 8. 仪表盘接口测试 - console.log('\n【8】仪表盘接口测试') - console.log('-'.repeat(40)) - - const dashboardRes = await request('GET', `/api/dashboard/summary?userId=${testUserId}`) - assert(dashboardRes.status === 200, '仪表盘状态码200') - checkResponseFormat(dashboardRes, '仪表盘') - assert(dashboardRes.data.data.totalBalance !== undefined, '仪表盘包含总余额') - assert(dashboardRes.data.data.monthIncome !== undefined, '仪表盘包含本月收入') - assert(dashboardRes.data.data.monthExpense !== undefined, '仪表盘包含本月支出') - - // 9. 清理测试数据 - console.log('\n【9】清理测试数据') - console.log('-'.repeat(40)) - - // 删除记录 - await request('DELETE', `/api/records/${testRecordId}`) - - // 删除预算 - await request('DELETE', `/api/budgets/${testBudgetId}`) - - // 删除账户 - await request('DELETE', `/api/accounts/${testAccountId}`) - - console.log('✅ 测试数据清理完成') - - } catch (error) { - console.error('❌ 测试过程出错:', error) - } - - // 输出测试报告 - console.log('\n' + '='.repeat(60)) - console.log('测试报告摘要') - console.log('='.repeat(60)) - console.log(`总测试数: ${testResults.tests.length}`) - console.log(`✅ 通过: ${testResults.passed}`) - console.log(`❌ 失败: ${testResults.failed}`) - console.log(`通过率: ${((testResults.passed / testResults.tests.length) * 100).toFixed(1)}%`) - console.log('='.repeat(60)) - - return testResults -} - -// 运行测试 -runTests().then(results => { - process.exit(results.failed > 0 ? 1 : 0) -})