174 lines
4.1 KiB
JavaScript
174 lines
4.1 KiB
JavaScript
|
|
#!/usr/bin/env node
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* API端点测试脚本
|
|||
|
|
* 用于验证后端API接口的正确性和一致性
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
const axios = require('axios');
|
|||
|
|
|
|||
|
|
// API配置
|
|||
|
|
const API_BASE_URL = process.env.API_BASE_URL || 'http://localhost:3100';
|
|||
|
|
const API_VERSION = process.env.API_VERSION || '/api/v1';
|
|||
|
|
|
|||
|
|
// 测试用例
|
|||
|
|
const testCases = [
|
|||
|
|
// 管理员接口
|
|||
|
|
{
|
|||
|
|
name: '管理员登录接口',
|
|||
|
|
method: 'POST',
|
|||
|
|
path: '/admin/login',
|
|||
|
|
expectedStatus: 200,
|
|||
|
|
data: {
|
|||
|
|
username: 'admin',
|
|||
|
|
password: 'admin123'
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
name: '获取管理员信息接口',
|
|||
|
|
method: 'GET',
|
|||
|
|
path: '/admin/profile',
|
|||
|
|
expectedStatus: 200,
|
|||
|
|
requiresAuth: true
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
name: '获取管理员列表接口',
|
|||
|
|
method: 'GET',
|
|||
|
|
path: '/admin/list',
|
|||
|
|
expectedStatus: 200,
|
|||
|
|
requiresAuth: true
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 用户接口
|
|||
|
|
{
|
|||
|
|
name: '用户登录接口',
|
|||
|
|
method: 'POST',
|
|||
|
|
path: '/auth/login',
|
|||
|
|
expectedStatus: 200,
|
|||
|
|
data: {
|
|||
|
|
username: 'user1',
|
|||
|
|
password: 'user123'
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
name: '获取用户信息接口',
|
|||
|
|
method: 'GET',
|
|||
|
|
path: '/users/profile',
|
|||
|
|
expectedStatus: 200,
|
|||
|
|
requiresAuth: true
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 系统接口
|
|||
|
|
{
|
|||
|
|
name: '健康检查接口',
|
|||
|
|
method: 'GET',
|
|||
|
|
path: '/health',
|
|||
|
|
expectedStatus: 200
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
name: '系统统计接口',
|
|||
|
|
method: 'GET',
|
|||
|
|
path: '/system-stats',
|
|||
|
|
expectedStatus: 200
|
|||
|
|
}
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
// 认证令牌
|
|||
|
|
let authToken = '';
|
|||
|
|
|
|||
|
|
async function testEndpoint(testCase) {
|
|||
|
|
try {
|
|||
|
|
const url = `${API_BASE_URL}${API_VERSION}${testCase.path}`;
|
|||
|
|
const config = {
|
|||
|
|
method: testCase.method.toLowerCase(),
|
|||
|
|
url: url,
|
|||
|
|
headers: {}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 添加认证头
|
|||
|
|
if (testCase.requiresAuth && authToken) {
|
|||
|
|
config.headers.Authorization = `Bearer ${authToken}`;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 添加请求数据
|
|||
|
|
if (testCase.data) {
|
|||
|
|
config.data = testCase.data;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const response = await axios(config);
|
|||
|
|
|
|||
|
|
// 检查状态码
|
|||
|
|
if (response.status === testCase.expectedStatus) {
|
|||
|
|
console.log(`✅ ${testCase.name} - 成功 (${response.status})`);
|
|||
|
|
|
|||
|
|
// 如果是登录接口,保存token
|
|||
|
|
if (testCase.path === '/admin/login' && response.data.data && response.data.data.token) {
|
|||
|
|
authToken = response.data.data.token;
|
|||
|
|
console.log(` 获取到认证令牌`);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
} else {
|
|||
|
|
console.log(`❌ ${testCase.name} - 状态码不匹配: 期望 ${testCase.expectedStatus}, 实际 ${response.status}`);
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
} catch (error) {
|
|||
|
|
if (error.response) {
|
|||
|
|
console.log(`❌ ${testCase.name} - 错误: ${error.response.status} ${error.response.statusText}`);
|
|||
|
|
if (error.response.data) {
|
|||
|
|
console.log(` 错误信息: ${JSON.stringify(error.response.data)}`);
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
console.log(`❌ ${testCase.name} - 网络错误: ${error.message}`);
|
|||
|
|
}
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async function runAllTests() {
|
|||
|
|
console.log('🚀 开始API端点测试');
|
|||
|
|
console.log(`📊 测试环境: ${API_BASE_URL}`);
|
|||
|
|
console.log(`🔗 API版本: ${API_VERSION}`);
|
|||
|
|
console.log('='.repeat(60));
|
|||
|
|
|
|||
|
|
let passed = 0;
|
|||
|
|
let failed = 0;
|
|||
|
|
|
|||
|
|
for (const testCase of testCases) {
|
|||
|
|
const result = await testEndpoint(testCase);
|
|||
|
|
if (result) {
|
|||
|
|
passed++;
|
|||
|
|
} else {
|
|||
|
|
failed++;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 添加短暂延迟,避免请求过于频繁
|
|||
|
|
await new Promise(resolve => setTimeout(resolve, 100));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
console.log('='.repeat(60));
|
|||
|
|
console.log('📊 测试结果统计:');
|
|||
|
|
console.log(`✅ 通过: ${passed}`);
|
|||
|
|
console.log(`❌ 失败: ${failed}`);
|
|||
|
|
console.log(`📈 成功率: ${((passed / (passed + failed)) * 100).toFixed(1)}%`);
|
|||
|
|
|
|||
|
|
if (failed === 0) {
|
|||
|
|
console.log('🎉 所有测试用例通过!');
|
|||
|
|
process.exit(0);
|
|||
|
|
} else {
|
|||
|
|
console.log('💥 存在失败的测试用例');
|
|||
|
|
process.exit(1);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 如果是直接运行此文件,则执行测试
|
|||
|
|
if (require.main === module) {
|
|||
|
|
runAllTests()
|
|||
|
|
.catch(error => {
|
|||
|
|
console.error('❌ 测试执行失败:', error.message);
|
|||
|
|
process.exit(1);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
module.exports = { runAllTests };
|