【8.进行接口测试】:通过 curl 进行接口自动化测试 / 通过 python 程序进行接口自动化测试 目录1. 总结接口设计文档2. 添加管理员账户3. 通过 curl 进行接口自动化测试4. 总结接口测试文档5. 把接口自动化用例整合成 python 程序1. 总结接口设计文档接口测试之前首先需要明确接口的定义规范。有哪些接口每个接口的作用每个接口的参数每个接口的返回值SPEC.md 参考文档并且结合代码中已经实现的接口总结一份完整的接口交互文档。包含每个接口的路径、参数、返回的响应结果、作用。总结出的文档写到 API.md 中。总结出的文档形如# API 接口文档 ## 基础信息 - **Base URL**: /api - **Content-Type**: application/json - **认证方式**: Session/Cookie通过 session_id Cookie --- ## 公开接口普通用户 ### 1. 题目列表 **GET** /api/problems 获取所有题目列表。 **响应示例** (200): json { problems: [ { id: 1, title: 两数之和, difficulty: Easy, created_at: 2026-04-24 10:00:00 } ] } --- ### 2. 题目详情 **GET** /api/problems/:id 获取指定题目的详细信息及测试用例。 **路径参数**: | 参数 | 类型 | 说明 | |------|------|------| | id | int | 题目 ID | **响应示例** (200): json { id: 1, title: 两数之和, difficulty: Easy, content: 给定一个整数数组 nums..., template: #include iostream\nusing namespace std;, created_at: 2026-04-24 10:00:00, test_cases: [ { id: 1, input: 2 7 11 15, expected: 9 15, position: 0 } ] } **错误响应**: - 400: {error: invalid problem id} - 404: {error: problem not found} --- ### 3. 提交代码 **POST** /api/submit 提交代码并执行。 **请求体**: | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | code | string | 是 | C 源代码 | | problem_id | int | 是 | 题目 ID | **响应示例** (200): json { status: AC, message: All test cases passed, passed: 3, total: 3, details: [ { case: 1, exit_code: 0, elapsed_ms: 15, stdout: 9 15, status: AC }, { case: 2, exit_code: 0, elapsed_ms: 12, stdout: 9 15, status: AC, expected: 9 15, actual: 9 15 } ] } **status 枚举值**: - AC: All Correct所有测试用例通过 - WA: Wrong Answer输出结果错误 - TLE: Time Limit Exceeded超时 - RE: Runtime Error运行时错误 - CE: Compilation Error编译错误 **错误响应**: - 400: {error: code is required} / {error: problem_id is required} - 404: {error: problem not found} --- ### 4. 用户注册 **POST** /api/register 注册新用户账号。 **请求体**: | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | username | string | 是 | 用户名3-64 字符 | | password | string | 是 | 密码至少 6 字符 | **响应示例** (201): json { message: user registered successfully, id: 1 } **错误响应**: - 400: {error: username is required} / {error: username must be between 3 and 64 characters} / {error: password must be at least 6 characters} - 409: {error: username already exists} - 500: {error: failed to create user} --- ### 5. 用户登录 **POST** /api/login 用户登录登录成功后在 Cookie 中设置 session_id。 **请求体**: | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | username | string | 是 | 用户名 | | password | string | 是 | 密码 | **响应示例** (200): json { message: login successful, username: testuser, role: user } **错误响应**: - 400: {error: username is required} / {error: password is required} - 401: {error: invalid username or password} --- ### 6. 用户登出 **POST** /api/logout 用户登出销毁当前会话。 **请求头**: - Cookie: session_idxxx **响应示例** (200): json { message: logout successful } --- ## 管理接口管理员 **注意**: 管理接口需要管理员权限role 为 admin ### 7. 新增题目 **POST** /api/admin/problems 创建新题目。 **请求头**: - Cookie: session_idxxx **请求体**: | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | title | string | 是 | 题目标题 | | difficulty | string | 是 | 难度等级Easy、Medium、Hard | | content | string | 是 | 题目描述Markdown 格式 | | template | string | 否 | 代码模板 | | test_cases | array | 否 | 测试用例数组 | **test_cases 数组元素**: | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | input | string | 是 | 输入数据 | | expected | string | 是 | 期望输出 | | position | int | 否 | 排序序号 | **响应示例** (201): json { id: 1, message: problem created successfully } **错误响应**: - 400: {error: title is required} / {error: difficulty is required} / {error: content is required} / {error: invalid difficulty, must be Easy, Medium, or Hard} - 500: {error: failed to save problem} --- ### 8. 删除题目 **DELETE** /api/admin/problems/:id 删除指定题目。 **路径参数**: | 参数 | 类型 | 说明 | |------|------|------| | id | int | 题目 ID | **请求头**: - Cookie: session_idxxx **响应示例** (200): json { message: problem deleted successfully } **错误响应**: - 400: {error: invalid problem id} - 500: {error: failed to delete problem} --- ## 数据模型 ### 题目 (Problem) | 字段 | 类型 | 说明 | |------|------|------| | id | int | 题目 ID | | title | string | 题目标题 | | difficulty | string | 难度Easy、Medium、Hard | | content | string | 题目描述 | | template | string | 代码模板 | | created_at | string | 创建时间 | ### 测试用例 (TestCase) | 字段 | 类型 | 说明 | |------|------|------| | id | int | 用例 ID | | problem_id | int | 所属题目 ID | | input | string | 输入数据 | | expected | string | 期望输出 | | position | int | 排序序号 | ### 用户 (User) | 字段 | 类型 | 说明 | |------|------|------| | id | int | 用户 ID | | username | string | 用户名 | | role | string | 角色user、admin | | created_at | string | 创建时间 | --- ## 错误码汇总 | HTTP 状态码 | 说明 | |-------------|------| | 200 | 请求成功 | | 201 | 创建成功 | | 400 | 请求参数错误 | | 401 | 认证失败 | | 404 | 资源不存在 | | 409 | 资源冲突如用户名已存在 | | 500 | 服务器内部错误 |根据这份接口文档就可以进行接口自动化测试了。正常来说API接口文档应该是在正式开发之前就确定好的。咱们本次开发中在创建SPEC.md阶段当时是有看到关于接口的定义但是没发现此处定义的接口并不完整详细。直到开发了一些功能之后才意识到这个问题。因此只能先完成开发再补充接口文档了。各位在开发时要记得把接口文档提前定义好。2. 添加管理员账户此处我们约定管理员用户名为 admin密码为 由于我们实现了密码加密功能因此直接在数据库中插入明文密码是无法正确进行登录的。而密码加密后的内容我们又无法手动计算得出。因此我们需要写一个辅助工具来构造管理员账户。实现一个小工具往数据库中插入管理员账户用户名是 admin密码是注意密码需要调用加密的逻辑向数据库中存储密文密码如果 admin 用户已经存在删除之前的用户重新插入这个 admin 用户.这样的小工具AI开发很快。我们运行这个程序即可在数据库中插入好管理员信息。3. 通过 curl 进行接口自动化测试API.md 根据当前文档中对于接口的描述通过 curl 命令的方式来构造 http 请求验证每个接口是能够正常工作的服务端已经启动直接进行测试.此时opencode 就会按照文档中的描述通过curl命令进行接口测试。注意由于opencode 在创建后台进程时疑似存在bug因此需要我们提前在另一个终端中把oj_server 启动好并告诉AI直接进行测试。4. 总结接口测试文档为了让接口自动化测试的步骤能 “固化” 下来避免下次测试时由于 AI 的随机性导致测试不通过我们可以让 AI 总结接口测试的过程。将上面的步骤总结成一个 基于 curl 的接口自动化测试文档.md便于未来进行重复的测试.随着程序开发的进展可能早期的单元测试会收到影响。因此随时多运行单元测试及时修复是开发时的一个重要习惯。总结的文档形如# 基于 curl 的接口自动化测试文档 ## 基础信息 - **Base URL**: http://localhost:8080/api - **Content-Type**: application/json - **认证方式**: Session/Cookie通过 session_id Cookie --- ## 准备工作 ### 启动服务器 bash ./build/oj_server ### 创建 Cookie 文件存放目录 bash mkdir -p /tmp --- ## 公开接口测试 ### 1. 获取题目列表 bash curl -s http://localhost:8080/api/problems **预期响应**: 200 OK返回题目列表 --- ### 2. 获取题目详情 bash # 正常情况 curl -s http://localhost:8080/api/problems/425 # 题目不存在 (404) curl -s http://localhost:8080/api/problems/999999 **预期响应**: - 200 OK: 返回题目详情及测试用例 - 404 Not Found: {error: problem not found} --- ### 3. 用户注册 bash # 正常注册 curl -s -X POST http://localhost:8080/api/register \ -H Content-Type: application/json \ -d {username:testuser,password:123456} # 用户名过短 (400) curl -s -X POST http://localhost:8080/api/register \ -H Content-Type: application/json \ -d {username:ab,password:123456} # 用户名已存在 (409) curl -s -X POST http://localhost:8080/api/register \ -H Content-Type: application/json \ -d {username:testuser,password:123456} **预期响应**: - 201 Created: {message: user registered successfully, id: 1} - 400 Bad Request: {error: username must be between 3 and 64 characters} - 409 Conflict: {error: username already exists} --- ### 4. 用户登录 bash # 普通用户登录 curl -s -X POST http://localhost:8080/api/login \ -H Content-Type: application/json \ -d {username:testuser,password:123456} \ -c /tmp/user_cookies.txt # 管理员登录 curl -s -X POST http://localhost:8080/api/login \ -H Content-Type: application/json \ -d {username:admin,password:admin123} \ -c /tmp/admin_cookies.txt **预期响应**: 200 OK返回用户信息及 role - 普通用户: {message: login successful, username: testuser, role: user} - 管理员: {message: login successful, username: admin, role: admin} --- ### 5. 用户登出 bash curl -s -X POST http://localhost:8080/api/logout -b /tmp/user_cookies.txt **预期响应**: 200 OK: {message: logout successful} --- ### 6. 提交代码 bash # 正常提交 curl -s -X POST http://localhost:8080/api/submit \ -H Content-Type: application/json \ -d { code: #include iostream\nusing namespace std;\nint main() { int a,b; cinab; coutabendl; return 0; }, problem_id: 425 } # 缺少 code 字段 (400) curl -s -X POST http://localhost:8080/api/submit \ -H Content-Type: application/json \ -d {problem_id: 425} # 题目不存在 (404) curl -s -X POST http://localhost:8080/api/submit \ -H Content-Type: application/json \ -d {code: #include iostream, problem_id: 999999} **预期响应**: - 200 OK: 返回执行结果包含 status (AC/WA/TLE/RE/CE)、passed/total 数量及详细结果 - 400 Bad Request: {error: code is required} - 404 Not Found: {error: problem not found} --- ## 管理接口测试需要管理员权限 ### 7. 创建题目 bash # 完整参数 curl -s -X POST http://localhost:8080/api/admin/problems \ -H Content-Type: application/json \ -b /tmp/admin_cookies.txt \ -d { title: 两数之和, difficulty: Easy, content: 给定一个整数数组..., template: #include iostream, test_cases: [ {input: 2 7 11 15, expected: 9, position: 0}, {input: 1 2 3, expected: 3, position: 1} ] } # 最小参数 curl -s -X POST http://localhost:8080/api/admin/problems \ -H Content-Type: application/json \ -b /tmp/admin_cookies.txt \ -d {title: Test, difficulty: Easy, content: Test content} # 缺少必填字段 (400) curl -s -X POST http://localhost:8080/api/admin/problems \ -H Content-Type: application/json \ -b /tmp/admin_cookies.txt \ -d {title: Test} # 难度值无效 (400) curl -s -X POST http://localhost:8080/api/admin/problems \ -H Content-Type: application/json \ -b /tmp/admin_cookies.txt \ -d {title: Test, difficulty: Invalid, content: Test} **预期响应**: - 201 Created: {id: 1, message: problem created successfully} - 400 Bad Request: {error: title is required} / {error: invalid difficulty, must be Easy, Medium, or Hard} --- ### 8. 删除题目 bash # 正常删除 curl -s -X DELETE http://localhost:8080/api/admin/problems/431 \ -b /tmp/admin_cookies.txt # 无效 ID (400) curl -s -X DELETE http://localhost:8080/api/admin/problems/invalid \ -b /tmp/admin_cookies.txt # 题目不存在 (500) curl -s -X DELETE http://localhost:8080/api/admin/problems/999999 \ -b /tmp/admin_cookies.txt **预期响应**: - 200 OK: {message: problem deleted successfully} - 400 Bad Request: {error: invalid problem id} - 500 Internal Server Error: {error: failed to delete problem} --- ## 权限测试 ### 测试非管理员用户访问管理接口 bash # 先用普通用户登录 curl -s -X POST http://localhost:8080/api/login \ -H Content-Type: application/json \ -d {username:testuser,password:123456} \ -c /tmp/user_cookies.txt # 尝试创建题目应失败 curl -s -X POST http://localhost:8080/api/admin/problems \ -H Content-Type: application/json \ -b /tmp/user_cookies.txt \ -d {title: Hack, difficulty: Easy, content: Test} --- ## 一键测试脚本 将以下内容保存为 test_api.sh可直接运行 bash #!/bin/bash BASE_URLhttp://localhost:8080/api echo 1. 测试获取题目列表 curl -s $BASE_URL/problems | jq . echo -e \n 2. 测试获取题目详情 curl -s $BASE_URL/problems/425 | jq . echo -e \n 3. 测试用户注册 curl -s -X POST $BASE_URL/register \ -H Content-Type: application/json \ -d {username:curluser,password:123456} | jq . echo -e \n 4. 测试用户登录 curl -s -X POST $BASE_URL/login \ -H Content-Type: application/json \ -d {username:admin,password:admin123} \ -c /tmp/admin_cookies.txt | jq . echo -e \n 5. 测试提交代码 curl -s -X POST $BASE_URL/submit \ -H Content-Type: application/json \ -d {code:#include iostream\nusing namespace std;\nint main(){int a,b;cinab;coutabendl;return 0;},problem_id:425} | jq . echo -e \n 6. 测试创建题目 curl -s -X POST $BASE_URL/admin/problems \ -H Content-Type: application/json \ -b /tmp/admin_cookies.txt \ -d {title:Curl Test,difficulty:Easy,content:Test} | jq . echo -e \n 7. 测试删除题目 curl -s -X DELETE $BASE_URL/admin/problems/432 \ -b /tmp/admin_cookies.txt | jq . echo -e \n 8. 测试登出 curl -s -X POST $BASE_URL/logout -b /tmp/admin_cookies.txt | jq . --- ## 错误码汇总 | HTTP 状态码 | 说明 | |-------------|------| | 200 | 请求成功 | | 201 | 创建成功 | | 400 | 请求参数错误 | | 401 | 认证失败 | | 404 | 资源不存在 | | 409 | 资源冲突如用户名已存在 | | 500 | 服务器内部错误 | --- ## status 枚举值 | 值 | 说明 | |----|------| | AC | All Correct所有测试用例通过 | | WA | Wrong Answer输出结果错误 | | TLE | Time Limit Exceeded超时 | | RE | Runtime Error运行时错误 | | CE | Compilation Error编译错误 |5. 把接口自动化用例整合成 python 程序通过LLM基于文档的方式进行接口测试虽然比较灵活但是也存在两个问题每次运行都需要消耗一定的token由于LLM的执行存在一定的“随机性”每次自行测试的结果不一定稳定。因此我们也可以把上述的测试过程转换成传统的基于 python 方式的接口自动化测试。根据 基于curl的接口自动化测试文档.md 中的内容把接口自动化测试通过 python 程序来进行实现测试代码放到 tests/python/ 中.此时opencode 会基于 requests 和 pytest 构建接口自动化测试这个过程需要安装一些依赖pip install -r requirements.txt --break-system-packages注意这里使用--break-system-packages选项是因为 python 默认不建议把第三方库进行全局安装为了防止出现版本冲突。但是由于我们此处并不涉及多个版本库共存的场景因此直接加上上述选项强制进行全局安装即可。接下来 opencode 就会根据前面总结的接口测试的步骤文档进行测试代码的开发。开发之后第一版程序大概率会跑不过很多响应的细节python 代码中不一定一步到位因此直接在 opencode 中运行测试我已经安装改好了 python 的依赖直接运行 pytest

相关新闻

最新新闻

LwIP协议栈深度解析:从内存管理到TCP调优的嵌入式网络实战

LwIP协议栈深度解析:从内存管理到TCP调优的嵌入式网络实战

1. 从一次网络调试的“灵异事件”说起几年前,我在一个基于STM32F407的工业网关项目上,遇到了一个至今记忆犹新的问题。设备作为TCP服务器,需要稳定接收来自上位机的数据包。在实验室里,一切运行完美,数据吞吐流畅&…

2026/8/1 8:34:26
ADC前端滤波电容设计误区:为何电容越大采样误差越大?

ADC前端滤波电容设计误区:为何电容越大采样误差越大?

在嵌入式开发或数据采集项目中,ADC(模数转换器)的精度和稳定性直接决定了整个系统的性能。很多工程师,尤其是刚接触硬件设计的开发者,常常会陷入一个误区:为了获得更“干净”的采样信号,在ADC的…

2026/8/1 8:34:26
散列表核心原理:哈希函数、冲突解决与动态扩容实战指南

散列表核心原理:哈希函数、冲突解决与动态扩容实战指南

1. 散列表:从“名字”到“座位”的快速寻址术如果你用过字典,无论是纸质的还是电子的,你肯定知道怎么快速找到一个词的解释:你不会从第一页开始一页一页翻,而是根据拼音或部首索引,直接跳到大概的页数。散列…

2026/8/1 8:34:26
2026成都智慧档案一体化建设新政落地:数实融合建设标准与主流服务选型评测

2026成都智慧档案一体化建设新政落地:数实融合建设标准与主流服务选型评测

导语:2026年依托全国档案“十五五”规划与人工智能应用试点落地要求,成都、四川全域机关单位、国企央企、公检法及医疗机构全面提速智慧档案一体化建设,正式告别传统“人工台账、软硬件分离、数实脱节”的管理模式。智慧档案一体化以国产化信…

2026/8/1 8:34:26
直流电机仿真实验:从模型搭建到动态特性分析

直流电机仿真实验:从模型搭建到动态特性分析

摘要 本文通过 MATLAB/Simulink 搭建直流电机仿真模型,详细分析了电机的额定参数计算、机械特性曲线绘制、不同工况下的稳态转速计算,并设计了完整的启动-正转-反转-制动控制仿真实验。文章包含完整的数学模型推导、仿真参数设置、结果验证和电路设计,为直流电机控制系统学…

2026/8/1 8:34:26
7月31日DeepSeek开放V4-Flash API公测:Agent能力跃升,或开启AI工程师新时代

7月31日DeepSeek开放V4-Flash API公测:Agent能力跃升,或开启AI工程师新时代

DeepSeek-V4-Flash公测开启:Agent能力全面跃升7月31日,DeepSeek正式向公众开放V4-Flash正式版API公测,其最突出的亮点是Agent能力大幅跃升。9项基准测试成绩的全面披露,多项指标远超此前的V4-Pro-Preview预览版,让“代…

2026/8/1 8:29:26