| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 |
- const { test, expect, request } = require('@playwright/test');
- const API_BASE_URL = 'https://ajy.danclub.cn/api';
- /**
- * 7.1 用户管理接口
- */
- test.describe('API-001: 获取用户列表', () => {
- test('GET /api/users', async ({ request }) => {
- const response = await request.get(`${API_BASE_URL}/users?page=1&pageSize=10`);
- expect(response.status()).toBe(200);
- const data = await response.json();
- expect(Array.isArray(data.list)).toBe(true);
- });
- });
- test.describe('API-002: 获取用户详情', () => {
- test('GET /api/users/:id', async ({ request }) => {
- const response = await request.get(`${API_BASE_URL}/users/U001`);
- expect(response.status()).toBe(200);
- const data = await response.json();
- expect(data.id).toBe('U001');
- });
- });
- test.describe('API-003: 新增用户', () => {
- test('POST /api/users', async ({ request }) => {
- const userData = {
- name: '测试用户',
- gender: '男',
- age: 35,
- phone: '13900000000',
- shoulderWidth: 42,
- bodyLength: 85
- };
- const response = await request.post(`${API_BASE_URL}/users`, { data: userData });
- expect(response.status()).toBe(201);
- const data = await response.json();
- expect(data.name).toBe('测试用户');
- });
- });
- test.describe('API-004: 更新用户', () => {
- test('PUT /api/users/:id', async ({ request }) => {
- const updateData = { name: '更新后的姓名' };
- const response = await request.put(`${API_BASE_URL}/users/U001`, { data: updateData });
- expect(response.status()).toBe(200);
- const data = await response.json();
- expect(data.name).toBe('更新后的姓名');
- });
- });
- test.describe('API-005: 生成穴位坐标', () => {
- test('POST /api/users/:id/acupoint-coordinates', async ({ request }) => {
- const response = await request.post(`${API_BASE_URL}/users/U001/acupoint-coordinates`);
- expect(response.status()).toBe(200);
- const data = await response.json();
- expect(Array.isArray(data.acupoints)).toBe(true);
- });
- });
- /**
- * 7.2 方案管理接口
- */
- test.describe('API-010: 获取方案列表', () => {
- test('GET /api/schemes', async ({ request }) => {
- const response = await request.get(`${API_BASE_URL}/schemes`);
- expect(response.status()).toBe(200);
- const data = await response.json();
- expect(Array.isArray(data.list)).toBe(true);
- });
- });
- test.describe('API-011: 获取方案详情', () => {
- test('GET /api/schemes/:id', async ({ request }) => {
- const response = await request.get(`${API_BASE_URL}/schemes/S001`);
- expect(response.status()).toBe(200);
- const data = await response.json();
- expect(data.id).toBe('S001');
- });
- });
- test.describe('API-012: 创建方案', () => {
- test('POST /api/schemes', async ({ request }) => {
- const schemeData = {
- name: '测试方案',
- mode: '一键艾灸',
- efficacy: '驱寒'
- };
- const response = await request.post(`${API_BASE_URL}/schemes`, { data: schemeData });
- expect(response.status()).toBe(201);
- const data = await response.json();
- expect(data.name).toBe('测试方案');
- });
- });
- test.describe('API-013: 发布方案', () => {
- test('POST /api/schemes/:id/publish', async ({ request }) => {
- const response = await request.post(`${API_BASE_URL}/schemes/S001/publish`);
- expect(response.status()).toBe(200);
- const data = await response.json();
- expect(data.status).toBe('已发布');
- });
- });
- test.describe('API-014: 同步圣手方案', () => {
- test('POST /api/users/:id/devices/:deviceId/expert-sync', async ({ request }) => {
- const response = await request.post(`${API_BASE_URL}/users/U001/devices/AJY001/expert-sync`);
- expect(response.status()).toBe(200);
- const data = await response.json();
- expect(data.syncedCount).toBeGreaterThan(0);
- });
- });
- /**
- * 8. 数据库测试
- * 需要直接访问数据库或通过API验证约束
- */
- test.describe('DB-001: 唯一性约束-手机号', () => {
- test('插入重复手机号', async ({ request }) => {
- const userData = { phone: '13800138000' };
- const response = await request.post(`${API_BASE_URL}/users`, { data: userData });
- expect(response.status()).toBeGreaterThanOrEqual(400);
- });
- });
- test.describe('DB-002: 唯一性约束-设备编号', () => {
- test('插入重复设备编号', async ({ request }) => {
- const deviceData = { deviceNo: 'AJY001' };
- const response = await request.post(`${API_BASE_URL}/devices`, { data: deviceData });
- expect(response.status()).toBeGreaterThanOrEqual(400);
- });
- });
- test.describe('DB-003: 主设备唯一性', () => {
- test('同一用户设置两个主设备', async ({ request }) => {
- const firstDevice = { userId: 'U001', deviceNo: 'AJY001', isMain: true };
- const secondDevice = { userId: 'U001', deviceNo: 'AJY002', isMain: true };
- await request.post(`${API_BASE_URL}/user-devices`, { data: firstDevice });
- const response = await request.post(`${API_BASE_URL}/user-devices`, { data: secondDevice });
- const data = await response.json();
- expect(data.isMain).toBe(true);
- });
- });
- test.describe('DB-004: 逻辑删除', () => {
- test('删除用户', async ({ request }) => {
- const response = await request.delete(`${API_BASE_URL}/users/U001`);
- expect(response.status()).toBe(200);
- const data = await response.json();
- expect(data.deleted).toBe(1);
- });
- });
- test.describe('DB-005: 外键级联', () => {
- test('删除用户下的设备绑定', async ({ request }) => {
- const response = await request.delete(`${API_BASE_URL}/users/U001`);
- const bindings = await request.get(`${API_BASE_URL}/user-devices?userId=U001`);
- const data = await bindings.json();
- expect(data.list.length).toBe(0);
- });
- });
- test.describe('DB-006: 数据类型验证', () => {
- test('插入超出范围的肩宽', async ({ request }) => {
- const userData = { shoulderWidth: 100 };
- const response = await request.post(`${API_BASE_URL}/users`, { data: userData });
- expect(response.status()).toBeGreaterThanOrEqual(400);
- });
- });
- /**
- * 9. 验收测试
- */
- test.describe('AT-001: 穴位定位精度', () => {
- test('完整指寸数据生成坐标', async ({ request }) => {
- const response = await request.post(`${API_BASE_URL}/algorithm/acupoint-generate`, {
- data: { shoulderWidth: 42, bodyLength: 85, gender: '男', cun1: 2.2, cun1_5: 3.3, cun3: 6.6 }
- });
- const data = await response.json();
- const errors = data.acupoints.map(a => a.error).filter(e => e > 2);
- expect(errors.length).toBe(0);
- });
- });
- test.describe('AT-002: 穴位库动态扩展', () => {
- test('新增穴位在方案中使用', async ({ request }) => {
- const acupointData = { name: '测试穴位', meridian: '督脉', efficacy: '驱寒' };
- await request.post(`${API_BASE_URL}/acupoints`, { data: acupointData });
- const schemes = await request.get(`${API_BASE_URL}/schemes`);
- const data = await schemes.json();
- expect(data.list.length).toBeGreaterThan(0);
- });
- });
- test.describe('AT-003: 8种专业模式', () => {
- test('创建8种功效方案', async ({ request }) => {
- const efficacies = ['驱寒', '祛湿', '清热', '补气', '养血', '活血', '安神', '理气'];
- for (const efficacy of efficacies) {
- const schemeData = { name: `${efficacy}方案`, mode: '专业模式', efficacy };
- const response = await request.post(`${API_BASE_URL}/schemes`, { data: schemeData });
- expect(response.status()).toBe(201);
- }
- });
- });
- test.describe('AT-004: 工艺语言生成', () => {
- test('���建��家方案生成设备指令', async ({ request }) => {
- const schemeData = { name: '专家方案', mode: '延年圣手', expertName: '测试专家' };
- const response = await request.post(`${API_BASE_URL}/schemes`, { data: schemeData });
- const data = await response.json();
- expect(data.instructions).toBeDefined();
- });
- });
- test.describe('AT-005: API响应时间', () => {
- test('核心API响应时间<200ms', async ({ request }) => {
- const times = [];
- for (let i = 0; i < 100; i++) {
- const start = Date.now();
- await request.get(`${API_BASE_URL}/users`);
- const time = Date.now() - start;
- times.push(time);
- }
- const avgTime = times.reduce((a, b) => a + b, 0) / times.length;
- expect(avgTime).toBeLessThan(200);
- });
- });
- test.describe('AT-006: 症状推荐覆盖率', () => {
- test('常见症状推荐覆盖率≥80%', async ({ request }) => {
- const symptoms = ['感冒', '发烧', '咳嗽', '头痛', '腰痛', '失眠', '胃痛', '痛经', '关节炎', '高血压'];
- let covered = 0;
- for (const symptom of symptoms) {
- const response = await request.get(`${API_BASE_URL}/schemes/recommend?symptom=${symptom}`);
- const data = await response.json();
- if (data.list && data.list.length > 0) covered++;
- }
- const coverage = (covered / symptoms.length) * 100;
- expect(coverage).toBeGreaterThanOrEqual(80);
- });
- });
|