Files
martial-mini/test/api-test.js
2025-12-12 01:44:41 +08:00

419 lines
14 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 武术比赛报名系统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);
});