This commit is contained in:
2025-12-12 01:44:41 +08:00
parent 21abcaff53
commit 2f1d732a36
46 changed files with 7756 additions and 484 deletions

418
test/api-test.js Normal file
View File

@@ -0,0 +1,418 @@
/**
* 武术比赛报名系统API自动化测试脚本
* 运行方式node test/api-test.js
* 需要先安装axios: npm install axios
*/
const axios = require('axios');
// 配置
const config = {
baseURL: 'http://your-api-domain.com', // 修改为你的API地址
timeout: 10000,
testUser: {
username: 'test_user',
password: 'test_password'
}
};
// 创建axios实例
const api = axios.create({
baseURL: config.baseURL,
timeout: config.timeout,
headers: {
'Content-Type': 'application/json'
}
});
// 测试结果统计
const testResults = {
total: 0,
passed: 0,
failed: 0,
errors: []
};
// 全局变量存储测试数据
let token = '';
let testCompetitionId = '';
let testAthleteId = '';
let testRegistrationId = '';
// 工具函数:断言
function assert(condition, testName, message) {
testResults.total++;
if (condition) {
testResults.passed++;
console.log(`${testName}`);
return true;
} else {
testResults.failed++;
console.error(`${testName}: ${message}`);
testResults.errors.push({ test: testName, message });
return false;
}
}
// 工具函数设置Token
function setToken(newToken) {
token = newToken;
api.defaults.headers['Blade-Auth'] = `Bearer ${token}`;
}
// 测试用例
const tests = {
// 1. 用户登录测试
async testLogin() {
console.log('\n【测试1】用户登录');
try {
const res = await api.post('/martial/auth/login', config.testUser);
assert(res.status === 200, '登录请求HTTP状态码', `期望200实际${res.status}`);
assert(res.data.code === 200, '登录业务状态码', `期望200实际${res.data.code}`);
assert(res.data.data && res.data.data.token, '返回Token', '未返回token');
if (res.data.data && res.data.data.token) {
setToken(res.data.data.token);
console.log(` Token: ${token.substring(0, 20)}...`);
}
return true;
} catch (err) {
assert(false, '登录请求', err.message);
return false;
}
},
// 2. 获取轮播图列表
async testBannerList() {
console.log('\n【测试2】获取轮播图列表');
try {
const res = await api.get('/martial/banner/list');
assert(res.status === 200, '轮播图请求HTTP状态码', `期望200实际${res.status}`);
assert(res.data.code === 200, '轮播图业务状态码', `期望200实际${res.data.code}`);
assert(Array.isArray(res.data.data), '返回数据格式', '期望数组格式');
console.log(` 轮播图数量: ${res.data.data ? res.data.data.length : 0}`);
} catch (err) {
assert(false, '轮播图请求', err.message);
}
},
// 3. 获取赛事列表
async testCompetitionList() {
console.log('\n【测试3】获取赛事列表');
try {
const res = await api.get('/martial/competition/list', {
params: { current: 1, size: 20 }
});
assert(res.status === 200, '赛事列表HTTP状态码', `期望200实际${res.status}`);
assert(res.data.code === 200, '赛事列表业务状态码', `期望200实际${res.data.code}`);
const hasRecords = res.data.data && res.data.data.records && res.data.data.records.length > 0;
const isArray = Array.isArray(res.data.data) && res.data.data.length > 0;
assert(hasRecords || isArray, '返回赛事数据', '未返回赛事数据');
if (hasRecords) {
testCompetitionId = res.data.data.records[0].id;
console.log(` 赛事数量: ${res.data.data.records.length}`);
console.log(` 测试赛事ID: ${testCompetitionId}`);
} else if (isArray) {
testCompetitionId = res.data.data[0].id;
console.log(` 赛事数量: ${res.data.data.length}`);
console.log(` 测试赛事ID: ${testCompetitionId}`);
}
} catch (err) {
assert(false, '赛事列表请求', err.message);
}
},
// 4. 获取赛事详情
async testCompetitionDetail() {
console.log('\n【测试4】获取赛事详情');
if (!testCompetitionId) {
console.log(' 跳过未获取到测试赛事ID');
return;
}
try {
const res = await api.get('/martial/competition/detail', {
params: { id: testCompetitionId }
});
assert(res.status === 200, '赛事详情HTTP状态码', `期望200实际${res.status}`);
assert(res.data.code === 200, '赛事详情业务状态码', `期望200实际${res.data.code}`);
assert(res.data.data && res.data.data.id, '返回赛事详情', '未返回详情数据');
if (res.data.data) {
console.log(` 赛事名称: ${res.data.data.name || res.data.data.title || '未知'}`);
console.log(` 赛事地点: ${res.data.data.location || res.data.data.address || '未知'}`);
}
} catch (err) {
assert(false, '赛事详情请求', err.message);
}
},
// 5. 获取选手列表
async testAthleteList() {
console.log('\n【测试5】获取选手列表');
try {
const res = await api.get('/martial/athlete/list', {
params: { current: 1, size: 100 }
});
assert(res.status === 200, '选手列表HTTP状态码', `期望200实际${res.status}`);
assert(res.data.code === 200, '选手列表业务状态码', `期望200实际${res.data.code}`);
const records = res.data.data && res.data.data.records ? res.data.data.records.length : 0;
const arrayLength = Array.isArray(res.data.data) ? res.data.data.length : 0;
console.log(` 选手数量: ${records || arrayLength}`);
} catch (err) {
assert(false, '选手列表请求', err.message);
}
},
// 6. 新增选手
async testCreateAthlete() {
console.log('\n【测试6】新增选手');
try {
const res = await api.post('/martial/athlete/submit', {
name: '测试选手_' + Date.now(),
idCard: '110101199001011234',
team: '测试队伍',
gender: '男',
phone: '13800138000'
});
assert(res.status === 200, '新增选手HTTP状态码', `期望200实际${res.status}`);
assert(res.data.code === 200, '新增选手业务状态码', `期望200实际${res.data.code}`);
if (res.data.data && res.data.data.id) {
testAthleteId = res.data.data.id;
console.log(` 新增选手ID: ${testAthleteId}`);
} else if (res.data.data) {
testAthleteId = res.data.data;
console.log(` 新增选手ID: ${testAthleteId}`);
}
} catch (err) {
assert(false, '<27><>增选手请求', err.message);
}
},
// 7. 获取选手详情
async testAthleteDetail() {
console.log('\n【测试7】获取选手详情');
if (!testAthleteId) {
console.log(' 跳过未获取到测试选手ID');
return;
}
try {
const res = await api.get('/martial/athlete/detail', {
params: { id: testAthleteId }
});
assert(res.status === 200, '选手详情HTTP状态码', `期望200实际${res.status}`);
assert(res.data.code === 200, '选手详情业务状态码', `期望200实际${res.data.code}`);
assert(res.data.data && res.data.data.name, '返回选手详情', '未返回详情数据');
if (res.data.data) {
console.log(` 选手姓名: ${res.data.data.name}`);
}
} catch (err) {
assert(false, '选手详情请求', err.message);
}
},
// 8. 获取报名项目列表
async testProjectList() {
console.log('\n【测试8】获取报名项目列表');
if (!testCompetitionId) {
console.log(' 跳过未获取到测试赛事ID');
return;
}
try {
const res = await api.get('/martial/project/list', {
params: { competitionId: testCompetitionId }
});
assert(res.status === 200, '项目列表HTTP状态码', `期望200实际${res.status}`);
assert(res.data.code === 200, '项目列表业务状态码', `期望200实际${res.data.code}`);
const records = res.data.data && res.data.data.records ? res.data.data.records.length : 0;
const arrayLength = Array.isArray(res.data.data) ? res.data.data.length : 0;
console.log(` 项目数量: ${records || arrayLength}`);
} catch (err) {
assert(false, '项目列表请求', err.message);
}
},
// 9. 获取我的报名列表
async testRegistrationList() {
console.log('\n【测试9】获取我的报名列表');
try {
const res = await api.get('/martial/registration/list', {
params: { current: 1, size: 20 }
});
assert(res.status === 200, '报名列表HTTP状态码', `期望200实际${res.status}`);
assert(res.data.code === 200, '报名列表业务状态码', `期望200实际${res.data.code}`);
const records = res.data.data && res.data.data.records ? res.data.data.records.length : 0;
const arrayLength = Array.isArray(res.data.data) ? res.data.data.length : 0;
console.log(` 报名记录数量: ${records || arrayLength}`);
} catch (err) {
assert(false, '报名列表请求', err.message);
}
},
// 10. 获取用户信息
async testUserInfo() {
console.log('\n【测试10】获取用户信息');
try {
const res = await api.get('/martial/user/info');
assert(res.status === 200, '用户信息HTTP状态码', `期望200实际${res.status}`);
assert(res.data.code === 200, '用户信息业务状态码', `期望200实际${res.data.code}`);
assert(res.data.data, '返回用户信息', '未返回用户数据');
if (res.data.data) {
console.log(` 用户名: ${res.data.data.name || res.data.data.username || '未知'}`);
}
} catch (err) {
assert(false, '用户信息请求', err.message);
}
},
// 11. 获取赛事信息公告
async testInfoList() {
console.log('\n【测试11】获取赛事信息公告');
if (!testCompetitionId) {
console.log(' 跳过未获取到测试赛事ID');
return;
}
try {
const res = await api.get('/martial/info/list', {
params: { competitionId: testCompetitionId }
});
assert(res.status === 200, '信息公告HTTP状态码', `期望200实际${res.status}`);
assert(res.data.code === 200, '信息公告业务状态码', `期望200实际${res.data.code}`);
const records = res.data.data && res.data.data.records ? res.data.data.records.length : 0;
const arrayLength = Array.isArray(res.data.data) ? res.data.data.length : 0;
console.log(` 公告数量: ${records || arrayLength}`);
} catch (err) {
assert(false, '信息公告请求', err.message);
}
},
// 12. 获取成绩列表
async testResultList() {
console.log('\n【测试12】获取成绩列表');
if (!testCompetitionId) {
console.log(' 跳过未获取到测试赛事ID');
return;
}
try {
const res = await api.get('/martial/result/list', {
params: { competitionId: testCompetitionId, current: 1, size: 100 }
});
assert(res.status === 200, '成绩列表HTTP状态码', `期望200实际${res.status}`);
assert(res.data.code === 200, '成绩列表业务状态码', `期望200实际${res.data.code}`);
const records = res.data.data && res.data.data.records ? res.data.data.records.length : 0;
const arrayLength = Array.isArray(res.data.data) ? res.data.data.length : 0;
console.log(` 成绩记录数量: ${records || arrayLength}`);
} catch (err) {
assert(false, '成绩列表请求', err.message);
}
},
// 13. 获取奖牌榜
async testMedalsList() {
console.log('\n【测试13】获取奖牌榜');
if (!testCompetitionId) {
console.log(' 跳过未获取到测试赛事ID');
return;
}
try {
const res = await api.get('/martial/medal/list', {
params: { competitionId: testCompetitionId }
});
assert(res.status === 200, '奖牌榜HTTP状态码', `期望200实际${res.status}`);
assert(res.data.code === 200, '奖牌榜业务状态码', `期望200实际${res.data.code}`);
const records = res.data.data && res.data.data.records ? res.data.data.records.length : 0;
const arrayLength = Array.isArray(res.data.data) ? res.data.data.length : 0;
console.log(` 奖牌榜队伍数: ${records || arrayLength}`);
} catch (err) {
assert(false, '奖牌榜请求', err.message);
}
},
// 14. 删除测试选手(清理数据)
async testDeleteAthlete() {
console.log('\n【测试14】删除测试选手清理数据');
if (!testAthleteId) {
console.log(' 跳过:未创建测试选手');
return;
}
try {
const res = await api.delete('/martial/athlete/remove', {
params: { ids: testAthleteId }
});
assert(res.status === 200, '删除选手HTTP状态码', `期望200实际${res.status}`);
assert(res.data.code === 200, '删除选手业务状态码', `期望200实际${res.data.code}`);
console.log(` 成功删除测试选手: ${testAthleteId}`);
} catch (err) {
assert(false, '删除选手请求', err.message);
}
}
};
// 运行所有测试
async function runAllTests() {
console.log('='.repeat(60));
console.log('武术比赛报名系统 - API自动化测试');
console.log('='.repeat(60));
console.log(`测试开始时间: ${new Date().toLocaleString()}`);
console.log(`API地址: ${config.baseURL}`);
const startTime = Date.now();
// 按顺序执行所有测试
for (const [name, testFn] of Object.entries(tests)) {
try {
await testFn();
} catch (err) {
console.error(`\n测试执行异常 [${name}]:`, err.message);
}
}
const duration = ((Date.now() - startTime) / 1000).toFixed(2);
// 输出测试结果
console.log('\n' + '='.repeat(60));
console.log('测试结果汇总');
console.log('='.repeat(60));
console.log(`总测试数: ${testResults.total}`);
console.log(`通过: ${testResults.passed}`);
console.log(`失败: ${testResults.failed}`);
console.log(`成功率: ${testResults.total > 0 ? ((testResults.passed / testResults.total) * 100).toFixed(2) : 0}%`);
console.log(`耗时: ${duration}`);
console.log(`测试结束时间: ${new Date().toLocaleString()}`);
if (testResults.failed > 0) {
console.log('\n失败的测试:');
testResults.errors.forEach((err, index) => {
console.log(`${index + 1}. ${err.test}: ${err.message}`);
});
}
console.log('='.repeat(60));
// 退出进程,返回状态码
process.exit(testResults.failed > 0 ? 1 : 0);
}
// 执行测试
runAllTests().catch(err => {
console.error('测试执行失败:', err);
process.exit(1);
});