完善e2e测试与后端测试,微信小程序端UI层测试暂未完成

This commit was merged in pull request #52.
This commit is contained in:
2026-07-23 20:16:31 +08:00
parent b689656faf
commit 86b7555943
37 changed files with 6819 additions and 5 deletions
@@ -0,0 +1,194 @@
/**
* P4-API - 会员端团课高级搜索 API 测试
* 流程:会员登录 → 按课程类型筛选 → 按标签筛选 → 类型+标签组合筛选 → 验证结果
*
* 使用 HTTP APIHMAC-SHA256 签名 + JWT Token
* 前置条件:后端服务 http://192.168.110.64:8084 已启动
*/
const api = require('../helpers/api-helper');
let authToken = null;
let memberId = null;
let typeId = null;
let labelId = null;
describe('P4-API - 团课高级搜索', () => {
// ════════════════════════════════════════════════════
// 步骤0:登录 & 准备筛选条件
// ════════════════════════════════════════════════════
beforeAll(async () => {
console.log('════════════════════════════════════════════');
console.log('P4-API - 团课高级搜索测试');
console.log('════════════════════════════════════════════');
const result = await api.memberLogin();
expect(result).not.toBeNull();
authToken = result.accessToken;
memberId = result.memberId;
console.log(`[P4-API] 会员登录成功: memberId=${memberId}`);
// 先获取课程类型列表,找第一个类型ID
const typeRes = await api.getCourseTypes();
if (api.isSuccess(typeRes)) {
const types = typeRes.data?.data || typeRes.data || [];
const records = Array.isArray(types) ? types : (types.records || types.content || []);
if (records.length > 0) {
typeId = records[0].id;
console.log(`[P4-API] 选择课程类型: id=${typeId}, name=${records[0].typeName || records[0].name}`);
}
}
// 尝试从课程列表获取第一个标签ID
try {
const searchRes = await api.searchCourses('', authToken);
if (api.isSuccess(searchRes)) {
const content = searchRes.data?.data?.content || searchRes.data?.content || searchRes.data || [];
const courses = Array.isArray(content) ? content : (content.records || []);
// 从第一个课程取标签
for (const course of courses) {
const labels = course.labels || course.labelList || [];
if (Array.isArray(labels) && labels.length > 0) {
const firstLabel = labels[0];
labelId = typeof firstLabel === 'object' ? firstLabel.id : firstLabel;
const name = typeof firstLabel === 'object' ? firstLabel.labelName : '';
console.log(`[P4-API] 选择标签: id=${labelId}, name=${name}`);
break;
}
}
}
} catch (e) {
console.warn('[P4-API] 获取标签失败:', e.message);
}
}, 60000);
// ════════════════════════════════════════════════════
// 步骤1:按课程类型筛选
// ════════════════════════════════════════════════════
describe('按课程类型筛选', () => {
test('TC-SEARCH-001: 按类型筛选应返回正确结果', async () => {
if (!typeId) {
console.warn('[TC-SEARCH-001] 无类型ID,跳过');
return;
}
const res = await api.searchCoursesByType(typeId, authToken);
expect(res.status).toBe(200);
const content = res.data?.data?.content || res.data?.content || res.data || [];
const courses = Array.isArray(content) ? content : (content.records || []);
console.log(`[TC-SEARCH-001] 类型筛选结果: ${courses.length} 个课程`);
// 验证所有返回课程的类型匹配
if (courses.length > 0) {
courses.slice(0, 3).forEach(c => {
console.log(` - ${c.courseName || c.name} (typeId=${c.courseTypeId || c.typeId})`);
});
}
expect(courses.length).toBeGreaterThanOrEqual(0);
});
});
// ════════════════════════════════════════════════════
// 步骤2:按标签筛选
// ════════════════════════════════════════════════════
describe('按标签筛选', () => {
test('TC-SEARCH-002: 按标签筛选应返回正确结果', async () => {
if (!labelId) {
console.warn('[TC-SEARCH-002] 无标签ID,跳过');
return;
}
const res = await api.searchCoursesByLabel(labelId, authToken);
expect(res.status).toBe(200);
const content = res.data?.data?.content || res.data?.content || res.data || [];
const courses = Array.isArray(content) ? content : (content.records || []);
console.log(`[TC-SEARCH-002] 标签筛选结果: ${courses.length} 个课程`);
if (courses.length > 0) {
courses.slice(0, 3).forEach(c => {
const labels = (c.labels || c.labelList || []).map(l =>
typeof l === 'object' ? l.labelName : l
);
console.log(` - ${c.courseName || c.name} (labels: [${labels.join(', ')}])`);
});
}
});
});
// ════════════════════════════════════════════════════
// 步骤3:类型+标签组合筛选
// ════════════════════════════════════════════════════
describe('类型+标签组合筛选', () => {
test('TC-SEARCH-003: 组合筛选应返回交集结果', async () => {
if (!typeId || !labelId) {
console.warn('[TC-SEARCH-003] 缺少类型或标签ID,跳过');
return;
}
const res = await api.searchCoursesCombined(typeId, labelId, authToken);
expect(res.status).toBe(200);
const content = res.data?.data?.content || res.data?.content || res.data || [];
const courses = Array.isArray(content) ? content : (content.records || []);
console.log(`[TC-SEARCH-003] 组合筛选结果: ${courses.length} 个课程`);
if (courses.length > 0) {
courses.slice(0, 3).forEach(c => {
console.log(` - ${c.courseName || c.name} (id=${c.id})`);
});
}
});
});
// ════════════════════════════════════════════════════
// 步骤4:边界场景
// ════════════════════════════════════════════════════
describe('边界场景', () => {
test('TC-SEARCH-004: 搜索不存在类型返回200(后端可能忽略无效筛选)', async () => {
const res = await api.searchCoursesByType(99999, authToken);
// 应确保API正常响应,即使筛选参数无效也不应该崩溃
console.log(`[TC-SEARCH-004] 不存在类型: status=${res.status}`);
expect(res.status).toBe(200);
});
test('TC-SEARCH-005: 搜索不存在标签返回200(后端可能忽略无效筛选)', async () => {
const res = await api.searchCoursesByLabel(99999, authToken);
console.log(`[TC-SEARCH-005] 不存在标签: status=${res.status}`);
expect(res.status).toBe(200);
});
test('TC-SEARCH-006: 空关键词搜索可返回全部课程', async () => {
const res = await api.searchCourses('', authToken);
expect(res.status).toBe(200);
const content = res.data?.data?.content || res.data?.content || res.data || [];
const courses = Array.isArray(content) ? content : (content.records || []);
console.log(`[TC-SEARCH-006] 空搜索返回: ${courses.length} 个课程`);
expect(courses.length).toBeGreaterThanOrEqual(0);
});
});
// ════════════════════════════════════════════════════
// 步骤5:总结
// ════════════════════════════════════════════════════
describe('总结', () => {
test('TC-P4-SUMMARY: 团课高级搜索汇总', () => {
console.log('');
console.log('════════════════════════════════════════════');
console.log('P4-API - 团课高级搜索测试结束');
console.log('════════════════════════════════════════════');
console.log(' 已测试:');
console.log(` 1. 按类型筛选 (typeId=${typeId || 'N/A'})`);
console.log(` 2. 按标签筛选 (labelId=${labelId || 'N/A'})`);
console.log(` 3. 类型+标签组合筛选`);
console.log(' 4. 不存在类型/标签边界');
console.log(' 5. 空关键词搜索');
console.log('════════════════════════════════════════════');
expect(memberId).toBeDefined();
expect(authToken).toBeTruthy();
});
});
});