埋点测试指南.md 11 KB

埋点系统测试指南

📋 测试前准备

1. 执行数据库建表SQL(必需)

⚠️ 重要:在执行任何测试前,必须先创建数据库表!

执行以下SQL创建表结构:

-- 埋点事件表
CREATE TABLE `store_track_event` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `event_type` varchar(50) NOT NULL COMMENT '事件类型',
  `event_category` varchar(50) NOT NULL COMMENT '事件分类',
  `user_id` int(11) DEFAULT NULL COMMENT '用户ID',
  `store_id` int(11) DEFAULT NULL COMMENT '店铺ID',
  `target_id` int(11) DEFAULT NULL COMMENT '目标对象ID',
  `target_type` varchar(50) DEFAULT NULL COMMENT '目标对象类型',
  `event_data` text COMMENT '事件附加数据(JSON格式)',
  `amount` decimal(10,2) DEFAULT NULL COMMENT '金额',
  `duration` bigint(20) DEFAULT NULL COMMENT '时长(毫秒)',
  `ip_address` varchar(50) DEFAULT NULL COMMENT 'IP地址',
  `user_agent` varchar(500) DEFAULT NULL COMMENT '用户代理',
  `device_type` varchar(20) DEFAULT NULL COMMENT '设备类型',
  `app_version` varchar(20) DEFAULT NULL COMMENT 'APP版本号',
  `event_time` datetime NOT NULL COMMENT '事件发生时间',
  `created_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `delete_flag` int(1) NOT NULL DEFAULT '0' COMMENT '删除标记',
  PRIMARY KEY (`id`),
  KEY `idx_store_id` (`store_id`),
  KEY `idx_user_id` (`user_id`),
  KEY `idx_event_type` (`event_type`),
  KEY `idx_event_category` (`event_category`),
  KEY `idx_event_time` (`event_time`),
  KEY `idx_store_event_time` (`store_id`,`event_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='埋点事件表';

-- 埋点统计表
CREATE TABLE `store_track_statistics` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `store_id` int(11) NOT NULL COMMENT '店铺ID',
  `stat_date` date NOT NULL COMMENT '统计日期',
  `stat_type` varchar(50) NOT NULL COMMENT '统计类型',
  `traffic_data` text COMMENT '流量数据(JSON格式)',
  `interaction_data` text COMMENT '互动数据(JSON格式)',
  `coupon_data` text COMMENT '优惠券数据(JSON格式)',
  `voucher_data` text COMMENT '代金券数据(JSON格式)',
  `service_data` text COMMENT '服务质量数据(JSON格式)',
  `price_ranking_data` text COMMENT '价目表排名数据(JSON格式)',
  `created_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updated_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_store_date_type` (`store_id`,`stat_date`,`stat_type`),
  KEY `idx_store_id` (`store_id`),
  KEY `idx_stat_date` (`stat_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='埋点统计表';

2. 确认服务配置

  • ✅ Redis连接正常
  • ✅ MySQL连接正常
  • ✅ 定时任务已启用(应用已配置 @EnableScheduling

🧪 测试步骤

测试1:前端埋点上报测试

1.1 使用Postman/curl测试上报接口

接口地址: POST http://localhost:8080/track/event

请求头:

Content-Type: application/json
Authorization: Bearer {your_token}  # 如果需要认证

请求体:

{
  "eventType": "VIEW",
  "eventCategory": "TRAFFIC",
  "storeId": 1001,
  "targetType": "STORE",
  "duration": 3000
}

预期结果:

{
  "code": 200,
  "success": true,
  "msg": "上报成功",
  "data": null
}

验证步骤:

  1. 调用接口后,检查Redis List中是否有数据

    # 连接到Redis,查看队列长度
    LLEN track:event:queue
       
    # 查看队列中的数据
    LRANGE track:event:queue 0 -1
    
  2. 等待10秒(定时任务消费间隔),检查数据库

    -- 查询最新埋点数据
    SELECT * FROM store_track_event 
    ORDER BY created_time DESC 
    LIMIT 10;
    

1.2 测试不同类型的事件

// 测试搜索事件
{
  "eventType": "SEARCH",
  "eventCategory": "TRAFFIC",
  "storeId": 1001,
  "targetType": "STORE"
}

// 测试收藏事件
{
  "eventType": "COLLECT",
  "eventCategory": "INTERACTION",
  "storeId": 1001,
  "targetType": "STORE"
}

// 测试分享事件
{
  "eventType": "SHARE",
  "eventCategory": "INTERACTION",
  "storeId": 1001,
  "targetType": "STORE"
}

// 测试价目表浏览
{
  "eventType": "PRICE_VIEW",
  "eventCategory": "PRICE",
  "storeId": 1001,
  "targetId": 2001,
  "targetType": "PRICE"
}

测试2:AOP自动埋点测试

2.1 在Controller方法上添加注解

在需要埋点的Controller方法上添加 @TrackEvent 注解:

@TrackEvent(
    eventType = "VIEW",
    eventCategory = "TRAFFIC",
    storeId = "#{#storeId}",
    targetType = "STORE"
)
@GetMapping("/store/detail")
public R<StoreInfo> getStoreDetail(@RequestParam Integer storeId) {
    // 业务逻辑
    return R.data(storeInfo);
}

2.2 测试步骤

  1. 调用业务接口(如:GET /store/detail?storeId=1001
  2. 接口正常返回
  3. 检查Redis List中是否自动生成了埋点数据
  4. 等待10秒,检查数据库是否写入

测试3:数据统计查询测试

3.1 查询经营数据

接口地址: GET http://localhost:8080/business/data

请求参数:

storeId=1001
startDate=2026-01-08
endDate=2026-01-14
category=TRAFFIC  # 可选:TRAFFIC, INTERACTION, COUPON, VOUCHER, SERVICE, PRICE

完整URL示例:

GET http://localhost:8080/business/data?storeId=1001&startDate=2026-01-08&endDate=2026-01-14

预期响应:

{
  "code": 200,
  "success": true,
  "msg": "查询成功",
  "data": {
    "trafficData": {
      "searchCount": 10,
      "viewCount": 50,
      "visitorCount": 30,
      "totalDuration": 150000,
      "avgDuration": 3000
    },
    "interactionData": {
      "collectCount": 5,
      "shareCount": 3,
      "checkinCount": 2,
      "consultCount": 1
    }
  }
}

3.2 数据对比测试

接口地址: GET http://localhost:8080/business/data/compare

请求参数:

storeId=1001
startDate1=2026-01-08
endDate1=2026-01-14
startDate2=2026-01-01
endDate2=2026-01-07

完整URL示例:

GET http://localhost:8080/business/data/compare?storeId=1001&startDate1=2026-01-08&endDate1=2026-01-14&startDate2=2026-01-01&endDate2=2026-01-07

预期响应:

{
  "code": 200,
  "success": true,
  "msg": "查询成功",
  "data": {
    "period1": {
      "trafficData": {
        "viewCount": 100
      }
    },
    "period2": {
      "trafficData": {
        "viewCount": 80
      }
    },
    "compare": {
      "traffic": {
        "viewCountChange": 25.00
      }
    }
  }
}

3.3 AI推荐测试

接口地址: GET http://localhost:8080/business/ai/recommendation

请求参数:

storeId=1001

完整URL示例:

GET http://localhost:8080/business/ai/recommendation?storeId=1001

预期响应:

{
  "code": 200,
  "success": true,
  "msg": "查询成功",
  "data": {
    "summary": "相较于其他同星级的店铺,您价目表中的锅包肉和烤羊腿价格远高于其他商家",
    "recommendations": [
      {
        "type": "PRICING",
        "title": "价格优化建议",
        "content": "寻找原材料更便宜的菜场、菜量降低、菜名突出特色,如锡林郭勒盟羔羊烤羊腿"
      }
    ]
  }
}

测试4:定时消费任务测试

4.1 验证消费任务是否正常运行

  1. 查看日志

    • 每10秒应该看到日志:成功消费X条埋点数据
    • 如果Redis List为空,不会有日志输出(这是正常的)
  2. 手动触发测试

    • 先上报多条埋点数据(10-20条)
    • 检查Redis List长度:LLEN track:event:queue
    • 等待10秒,再次检查:LLEN track:event:queue(应该为0或减少)
    • 查询数据库确认数据已写入

4.2 分布式锁测试

如果有多个服务实例,验证分布式锁是否生效:

  • 只有一个实例能消费数据
  • 不会出现重复消费

📊 完整测试流程示例

流程1:完整的埋点到统计流程

# 步骤1: 上报多条埋点数据
curl -X POST http://localhost:8080/track/event \
  -H "Content-Type: application/json" \
  -d '{"eventType":"VIEW","eventCategory":"TRAFFIC","storeId":1001,"targetType":"STORE","duration":3000}'

curl -X POST http://localhost:8080/track/event \
  -H "Content-Type: application/json" \
  -d '{"eventType":"SEARCH","eventCategory":"TRAFFIC","storeId":1001,"targetType":"STORE"}'

curl -X POST http://localhost:8080/track/event \
  -H "Content-Type: application/json" \
  -d '{"eventType":"COLLECT","eventCategory":"INTERACTION","storeId":1001,"targetType":"STORE"}'

# 步骤2: 检查Redis List
# 连接到Redis执行: LLEN track:event:queue

# 步骤3: 等待10秒,定时任务会自动消费

# 步骤4: 查询数据库验证数据已写入
# SELECT COUNT(*) FROM store_track_event WHERE store_id = 1001;

# 步骤5: 查询统计数据
curl "http://localhost:8080/business/data?storeId=1001&startDate=2026-01-08&endDate=2026-01-14"

🔍 测试检查清单

✅ 功能测试

  • 前端埋点上报接口正常
  • AOP自动埋点正常工作
  • Redis List正常写入
  • 定时任务正常消费
  • 数据库正常写入
  • 统计数据查询正常
  • 数据对比功能正常
  • AI推荐接口正常(如已实现)

✅ 性能测试

  • 批量上报100条数据,验证性能
  • 定时任务消费速度是否正常
  • 统计查询响应时间是否可接受

✅ 异常测试

  • Redis不可用时,系统是否降级
  • 数据库不可用时,是否有异常处理
  • 异常数据是否会被正确处理

🐛 常见问题排查

问题1:埋点数据没有写入数据库

检查项:

  1. 检查Redis List是否有数据:LLEN track:event:queue
  2. 查看定时任务日志,是否有错误
  3. 检查数据库连接是否正常
  4. 检查表结构是否正确创建

问题2:定时任务没有执行

检查项:

  1. 确认应用已启用 @EnableScheduling
  2. 检查 TrackEventConsumer 类是否被Spring管理(@Component
  3. 查看应用启动日志,确认定时任务配置加载

问题3:统计数据为空

检查项:

  1. 确认有埋点数据写入数据库
  2. 确认查询的时间范围正确
  3. 检查 getTrafficData() 等方法是否有TODO未实现

问题4:AOP切面不生效

检查项:

  1. 确认 @TrackEvent 注解在正确的方法上
  2. 确认 TrackEventAspect 类被Spring管理
  3. 检查切面执行顺序(@Order

📝 测试报告模板

### 测试日期: 2026-01-14
### 测试人员: [姓名]

#### 测试结果
- ✅ 前端埋点上报: 通过
- ✅ AOP自动埋点: 通过
- ✅ Redis队列: 正常
- ✅ 定时消费: 正常
- ✅ 统计查询: 通过
- ⚠️ AI推荐: 待完善

#### 发现问题
1. [问题描述]

#### 建议
1. [建议内容]

🚀 下一步

  1. 完善统计逻辑:实现Service中的TODO(优惠券、代金券、服务质量统计)
  2. 优化性能:对统计数据添加缓存
  3. 监控告警:添加Redis List长度监控
  4. 数据清理:实现历史数据清理策略