test_exam.md 8.2 KB

routers/exam.py 接口测试文档

文件功能概述

该文件提供考试相关的接口,包括:

  • 生成考试提示词(批量 / 单题)
  • 修改考试题目内容
  • 重新生成单道题目

所有接口均需要 Token 认证。

路由前缀:/apiv1(以 routers/__init__.py 中注册为准)


接口列表


1. POST /apiv1/exam/build_prompt — 生成考试提示词

功能说明: 根据考试类型、主题、难度和题目数量,拼接生成用于 AI 出题的提示词字符串。不调用 AI,仅返回 prompt 文本。

是否需要认证:

请求方式: POST

请求体(JSON): | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | exam_type | string | 是 | 考试类型(如 "单选题"、"判断题"、"填空题") | | topic | string | 是 | 考试主题 | | difficulty | string | 是 | 难度等级(如 "简单"、"中等"、"困难") | | question_count | int | 是 | 题目数量 |

测试用例:

用例 1:正常生成提示词

// 请求
POST /apiv1/exam/build_prompt
token: <有效Token>
Content-Type: application/json

{
  "exam_type": "单选题",
  "topic": "隧道施工安全",
  "difficulty": "中等",
  "question_count": 10
}

// 预期响应 (HTTP 200)
{
  "statusCode": 200,
  "msg": "success",
  "data": {
    "prompt": "请生成10道关于隧道施工安全的单选题,难度为中等。"
  }
}

用例 2:不同参数组合

// 请求
POST /apiv1/exam/build_prompt
token: <有效Token>
Content-Type: application/json

{
  "exam_type": "判断题",
  "topic": "桥梁工程",
  "difficulty": "简单",
  "question_count": 5
}

// 预期响应 (HTTP 200)
{
  "statusCode": 200,
  "msg": "success",
  "data": {
    "prompt": "请生成5道关于桥梁工程的判断题,难度为简单。"
  }
}

用例 3:未认证

// 请求(不带 Token)
POST /apiv1/exam/build_prompt
Content-Type: application/json

{
  "exam_type": "单选题",
  "topic": "测试",
  "difficulty": "简单",
  "question_count": 1
}

// 预期响应 (HTTP 401)
{
  "statusCode": 401,
  "msg": "未提供认证Token"
}

用例 4:缺少必填字段(由 Pydantic 校验)

// 请求
POST /apiv1/exam/build_prompt
token: <有效Token>
Content-Type: application/json

{
  "exam_type": "单选题",
  "topic": "隧道施工安全"
}

// 预期响应 (HTTP 422)
{
  "detail": [
    {
      "loc": ["body", "difficulty"],
      "msg": "field required",
      "type": "value_error.missing"
    },
    {
      "loc": ["body", "question_count"],
      "msg": "field required",
      "type": "value_error.missing"
    }
  ]
}

2. POST /apiv1/exam/build_single_prompt — 生成单题提示词

功能说明: 根据题目类型、主题和难度,拼接生成用于 AI 出单道题的提示词字符串。不调用 AI,仅返回 prompt 文本。

是否需要认证:

请求方式: POST

请求体(JSON): | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | question_type | string | 是 | 题目类型(如 "单选题"、"多选题") | | topic | string | 是 | 题目主题 | | difficulty | string | 是 | 难度等级 |

测试用例:

用例 1:正常生成单题提示词

// 请求
POST /apiv1/exam/build_single_prompt
token: <有效Token>
Content-Type: application/json

{
  "question_type": "多选题",
  "topic": "路基施工规范",
  "difficulty": "困难"
}

// 预期响应 (HTTP 200)
{
  "statusCode": 200,
  "msg": "success",
  "data": {
    "prompt": "请生成1道关于路基施工规范的多选题,难度为困难。"
  }
}

用例 2:未认证

// 请求
POST /apiv1/exam/build_single_prompt

// 预期响应 (HTTP 401)
{
  "statusCode": 401,
  "msg": "未提供认证Token"
}

用例 3:缺少必填字段

// 请求
POST /apiv1/exam/build_single_prompt
token: <有效Token>
Content-Type: application/json

{
  "question_type": "单选题"
}

// 预期响应 (HTTP 422)
{
  "detail": [
    {
      "loc": ["body", "topic"],
      "msg": "field required",
      "type": "value_error.missing"
    },
    {
      "loc": ["body", "difficulty"],
      "msg": "field required",
      "type": "value_error.missing"
    }
  ]
}

3. POST /apiv1/re_modify_question — 修改考试题目

功能说明: 修改指定对话下 type='ai' 的 AI 消息内容。用于用户手动编辑/修正 AI 生成的考试题目。

是否需要认证:

请求方式: POST

请求体(JSON): | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | ai_conversation_id | int | 是 | 对话 ID | | content | string | 是 | 修改后的题目内容 |

业务逻辑:

  • 通过 ai_conversation_id + type='ai' 条件查找 AIMessage 记录
  • 直接 update 匹配到的所有记录的 content 字段
  • 若无匹配记录则返回 404

测试用例:

用例 1:正常修改

// 请求
POST /apiv1/re_modify_question
token: <有效Token>
Content-Type: application/json

{
  "ai_conversation_id": 4,
  "content": "[{\"question\": \"修改后的题目\", \"options\": [\"A\", \"B\", \"C\", \"D\"], \"answer\": \"A\"}]"
}

// 预期响应 (HTTP 200)
{
  "statusCode": 200,
  "msg": "success"
}

用例 2:对话不存在或无 AI 消息

// 请求
POST /apiv1/re_modify_question
token: <有效Token>
Content-Type: application/json

{
  "ai_conversation_id": 99999,
  "content": "测试内容"
}

// 预期响应 (HTTP 200, 业务码 404)
{
  "statusCode": 404,
  "msg": "消息不存在"
}

用例 3:未认证

// 请求
POST /apiv1/re_modify_question

// 预期响应 (HTTP 401)
{
  "statusCode": 401,
  "msg": "未提供认证Token"
}

4. POST /apiv1/re_produce_single_question — 重新生成单题

功能说明: 基于原对话中的 AI 消息和给出的重新生成原因,返回重新生成的题目。

注意: 当前代码实际未调用 AI 服务进行重新生成,仅返回一个包含 regenerate_reason 的占位文本。

是否需要认证:

请求方式: POST

请求体(JSON): | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | ai_conversation_id | int | 是 | 对话 ID | | regenerate_reason | string | 是 | 重新生成的原因 |

业务逻辑:

  • 查找 ai_conversation_id + type='ai' 的消息
  • 若不存在返回 404
  • 若存在,返回重新生成的题目文本(当前为占位实现)

测试用例:

用例 1:正常重新生成

// 请求
POST /apiv1/re_produce_single_question
token: <有效Token>
Content-Type: application/json

{
  "ai_conversation_id": 4,
  "regenerate_reason": "题目难度过低"
}

// 预期响应 (HTTP 200)
{
  "statusCode": 200,
  "msg": "success",
  "data": {
    "ai_conversation_id": 4,
    "new_question": "重新生成的题目(原因:题目难度过低)"
  }
}

用例 2:对话不存在或无 AI 消息

// 请求
POST /apiv1/re_produce_single_question
token: <有效Token>
Content-Type: application/json

{
  "ai_conversation_id": 99999,
  "regenerate_reason": "测试"
}

// 预期响应 (HTTP 200, 业务码 404)
{
  "statusCode": 404,
  "msg": "消息不存在"
}

用例 3:未认证

// 请求
POST /apiv1/re_produce_single_question

// 预期响应 (HTTP 401)
{
  "statusCode": 401,
  "msg": "未提供认证Token"
}

依赖说明

依赖项 说明
database.get_db SQLAlchemy 数据库会话
models.chat.AIMessage AI 消息模型(字段:id, ai_conversation_id, type, content 等)
services.qwen_service Qwen AI 服务(已导入但当前代码中未实际调用)
request.state.user 从中间件注入的用户信息

代码备注

  1. build_promptbuild_single_prompt 仅做字符串拼接,不调用 AI 服务,实际 AI 调用由前端拿到 prompt 后通过 chat 接口完成。
  2. re_modify_question 使用 update 批量更新所有匹配 ai_conversation_id + type='ai' 的记录——如果同一对话有多条 AI 消息,会全部被覆盖。
  3. re_produce_single_question 当前为占位实现,new_question 只是拼接字符串,未真正调用 AI 重新生成。