Files
map-client-vue/STOP_GENERATION_TEST.md
2025-10-15 15:07:45 +08:00

5.4 KiB
Raw Blame History

停止生成功能测试指南

快速测试

测试步骤

  1. 启动开发服务器

    cd web
    npm run dev
    
  2. 创建测试场景

    • 打开浏览器访问应用
    • 确保已连接至少一个模型服务
    • 创建或选择一个对话
  3. 测试停止按钮

    场景 1正常停止

    1. 输入一个较长的问题(例如:"请详细解释量子计算的原理,包括量子叠加、量子纠缠等概念"
    2. 点击"确认"按钮发送
    3. 等待 AI 开始回复(看到文字开始输出)
    4. 立即点击"停止"按钮
    5. 验证:
       - ✅ 输出立即停止
       - ✅ 消息显示"已停止"的黄色标签
       - ✅ 已生成的内容完整显示
       - ✅ 可以看到操作按钮(复制、重新生成、删除)
       - ✅ 输入框恢复可用
    

    场景 2快速停止

    1. 输入问题并发送
    2. 在 AI 输出第一个字后立即点击停止
    3. 验证:即使只输出了很少内容,也能正确停止
    

    场景 3继续对话

    1. 停止一条消息后
    2. 立即发送新消息
    3. 验证:新消息能正常发送和接收
    

    场景 4重新生成

    1. 停止一条消息
    2. 点击该消息的"重新生成"按钮
    3. 验证:能重新生成完整回复
    

检查点

UI 检查

  • 按钮文字正确切换("确认" ↔ "停止"
  • 按钮颜色正确变化primary ↔ error
  • 停止的消息显示黄色"已停止"标签
  • 停止的消息能显示操作按钮
  • 输入框在发送时禁用,停止后恢复

功能检查

  • 点击停止后流式输出立即中断
  • 已生成的内容被保留
  • 可以复制停止的消息内容
  • 可以重新生成停止的消息
  • 可以删除停止的消息
  • 停止后可以继续发送新消息

控制台日志检查

打开浏览器控制台,点击停止时应该看到:

🛑 [handleStopGeneration] 用户请求停止生成
🛑 [makeChatRequestStream] 检测到中止信号,停止读取流
⚠️ [makeChatRequestStream] 请求被中止: 用户中止操作
⏸️ [sendMessageStream] 用户主动停止生成,保留已生成内容

常见问题排查

问题 1点击停止按钮没反应

原因:按钮事件未正确绑定 检查

  • 查看控制台是否有 JS 错误
  • 确认 handleButtonClick 函数存在
  • 确认 store.state.isSending 状态正确

问题 2输出没有停止

原因:中止信号未正确传递或检查 检查

  • 确认 state.abortController 已创建
  • 确认 signal 正确传递到 API 调用
  • 确认流式读取循环中检查了 signal.aborted

问题 3停止后显示错误

原因:未正确处理 AbortError 检查

  • 查看 chatService.ts 中的 catch 块
  • 确认区分了 AbortError 和其他错误
  • 确认 paused 状态设置正确

问题 4停止后无法发送新消息

原因isSending 状态未重置 检查

  • 确认 finally 块执行
  • 确认 state.isSending = false
  • 确认 abortController 被清空

调试模式

如需详细调试,在控制台运行:

// 查看当前状态
console.log('isSending:', store.state.isSending)
console.log('abortController:', store.state.abortController)
console.log('currentTopicId:', store.state.currentTopicId)
console.log('messages:', store.state.messages)

// 监听状态变化
watch(() => store.state.isSending, (val) => {
  console.log('isSending changed:', val)
})

性能验证

测量停止响应时间:

// 在点击停止前
const stopTime = performance.now()

// 点击停止

// 在停止完成后(看控制台日志)
const endTime = performance.now()
console.log('停止响应时间:', endTime - stopTime, 'ms')

// 预期:< 100ms

自动化测试(可选)

如果要编写自动化测试:

describe('Stop Generation', () => {
  it('should stop streaming when stop button clicked', async () => {
    // 模拟发送消息
    const promise = store.sendMessageStream('test message')
    
    // 等待开始发送
    await nextTick()
    expect(store.state.isSending).toBe(true)
    
    // 停止生成
    store.stopGeneration()
    
    // 验证状态
    expect(store.state.isSending).toBe(false)
    expect(store.state.abortController).toBe(null)
  })
  
  it('should mark message as paused', async () => {
    // 发送并停止
    const promise = store.sendMessageStream('test')
    await nextTick()
    store.stopGeneration()
    await promise.catch(() => {}) // 忽略中止错误
    
    // 检查最后一条消息
    const lastMessage = store.state.messages[store.state.messages.length - 1]
    expect(lastMessage.status).toBe('paused')
  })
})

成功标准

所有以下条件都满足才算修复成功

  1. 点击停止按钮有明显反应(按钮状态变化)
  2. 流式输出在 100ms 内完全停止
  3. 停止的消息显示"已停止"标签而非"发送失败"
  4. 已生成的内容完整保留
  5. 停止后立即可以发送新消息
  6. 可以对停止的消息进行各种操作
  7. 控制台无错误日志AbortError 除外)
  8. 连续多次停止-发送循环不会出现问题

回归测试

确保修复不影响其他功能:

  • 正常发送消息仍然工作
  • 消息历史正确保存
  • 话题切换正常
  • MCP 工具调用正常
  • 多模型切换正常