datai/datai-scenes/datai-scene-salesforce/docs/api-docs/2026-02-04-002-03-api.md

523 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# API 文档 - 测试执行(重构版)
## 元数据
- 需求编号002-03
- 文档版本v2.0.0
- 创建时间2026-02-04
- 创建人AI Assistant
- 状态:已完成
## API 概述
测试执行 API 提供 Salesforce Apex 测试的完整功能,包括运行测试(全部、按类、按包、按方法)、查询测试结果、查询代码覆盖率、查询 Flow 覆盖率等。所有接口都使用 source org 类型进行测试执行。
### 基础信息
- **Base URL**`/apex/test`
- **Content-Type**`application/json`
- **认证方式**JWT Token通过 Header 传递)
## 接口列表
### 1. 运行所有测试
#### 接口说明
运行 Salesforce Org 中的所有 Apex 测试。
- **请求方式**POST
- **请求路径**`/apex/test/run-all`
- **权限要求**`apex:test:run`
#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| skipCodeCoverage | Boolean | 否 | 是否跳过代码覆盖率检查,默认 false |
| maxFailedTests | Integer | 否 | 最大失败测试数,默认 -1不限制 |
#### 请求示例
```json
{
"skipCodeCoverage": false,
"maxFailedTests": -1
}
```
#### 响应参数
| 参数名 | 类型 | 说明 |
|--------|------|------|
| code | Integer | 状态码200 成功,其他失败) |
| msg | String | 提示信息 |
| data | Object | 测试执行结果 |
| data.numTestsRun | Integer | 运行的测试数量 |
| data.numFailures | Integer | 失败的测试数量 |
| data.totalTime | Double | 总执行时间(毫秒) |
| data.successes | Array | 成功的测试结果数组 |
| data.failures | Array | 失败的测试结果数组 |
| data.codeCoverage | Array | 代码覆盖率结果数组 |
| data.flowCoverage | Array | Flow 覆盖率结果数组 |
#### 成功响应示例
```json
{
"code": 200,
"msg": "操作成功",
"data": {
"numTestsRun": 100,
"numFailures": 5,
"totalTime": 15000.5,
"successes": [
{
"id": "01pxx000000xxxx",
"name": "AccountTriggerTest",
"methodName": "testInsert",
"className": "AccountTriggerTest",
"time": 150.5,
"message": null
}
],
"failures": [
{
"id": "01pxx000000xxxx",
"name": "ContactTriggerTest",
"methodName": "testUpdate",
"className": "ContactTriggerTest",
"message": "Assertion failed",
"stackTrace": "...",
"time": 200.0
}
],
"codeCoverage": [
{
"id": "01pxx000000xxxx",
"name": "AccountTrigger",
"type": "Trigger",
"coveragePercent": 85.5
}
],
"flowCoverage": [
{
"id": "301xx000000xxxx",
"name": "Account_Automation",
"type": "AutoLaunchedFlow",
"coveragePercent": 90.0
}
]
}
}
```
#### 失败响应示例
```json
{
"code": 500,
"msg": "运行测试失败: 连接超时"
}
```
---
### 2. 按类运行测试
#### 接口说明
运行指定 Apex 类的测试。
- **请求方式**POST
- **请求路径**`/apex/test/run-by-classes`
- **权限要求**`apex:test:run`
#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| classes | Array<String> | 是 | 要测试的类名称数组 |
| namespace | String | 否 | 命名空间 |
| skipCodeCoverage | Boolean | 否 | 是否跳过代码覆盖率检查,默认 false |
| maxFailedTests | Integer | 否 | 最大失败测试数,默认 -1不限制 |
#### 请求示例
```json
{
"classes": ["AccountTriggerTest", "ContactTriggerTest"],
"namespace": "",
"skipCodeCoverage": false,
"maxFailedTests": -1
}
```
#### 响应参数
同「运行所有测试」接口。
---
### 3. 按包运行测试
#### 接口说明
运行指定包中的所有 Apex 测试。
- **请求方式**POST
- **请求路径**`/apex/test/run-by-packages`
- **权限要求**`apex:test:run`
#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| packages | Array<String> | 是 | 要测试的包数组 |
| namespace | String | 否 | 命名空间 |
| skipCodeCoverage | Boolean | 否 | 是否跳过代码覆盖率检查,默认 false |
| maxFailedTests | Integer | 否 | 最大失败测试数,默认 -1不限制 |
#### 请求示例
```json
{
"packages": ["com.example.tests", "com.example.integration"],
"namespace": "",
"skipCodeCoverage": false,
"maxFailedTests": -1
}
```
#### 响应参数
同「运行所有测试」接口。
---
### 4. 按方法运行测试
#### 接口说明
运行指定的 Apex 测试方法。
- **请求方式**POST
- **请求路径**`/apex/test/run-by-methods`
- **权限要求**`apex:test:run`
#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| tests | Array<Object> | 是 | 要运行的测试方法数组 |
| tests[].classId | String | 否 | 测试类 ID |
| tests[].className | String | 是 | 测试类名称 |
| tests[].testMethods | Array<String> | 是 | 要运行的测试方法名称数组 |
| namespace | String | 否 | 命名空间 |
| skipCodeCoverage | Boolean | 否 | 是否跳过代码覆盖率检查,默认 false |
| maxFailedTests | Integer | 否 | 最大失败测试数,默认 -1不限制 |
#### 请求示例
```json
{
"tests": [
{
"className": "AccountTriggerTest",
"testMethods": ["testInsert", "testUpdate"]
},
{
"className": "ContactTriggerTest",
"testMethods": ["testDelete"]
}
],
"namespace": "",
"skipCodeCoverage": false,
"maxFailedTests": -1
}
```
#### 响应参数
同「运行所有测试」接口。
---
### 5. 查询测试成功详情
#### 接口说明
查询指定测试结果的成功详情。
- **请求方式**GET
- **请求路径**`/apex/test/successes`
- **权限要求**`apex:test:query`
#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| testResultId | String | 是 | 测试结果 ID |
| pageNum | Integer | 否 | 页码,默认 1 |
| pageSize | Integer | 否 | 每页大小,默认 10 |
#### 请求示例
```
GET /apex/test/successes?testResultId=12345&pageNum=1&pageSize=10
```
#### 响应参数
| 参数名 | 类型 | 说明 |
|--------|------|------|
| code | Integer | 状态码200 成功,其他失败) |
| msg | String | 提示信息 |
| data | Object | 分页结果 |
| data.total | Integer | 总记录数 |
| data.list | Array | 测试成功详情列表 |
| data.list[].id | String | 测试 ID |
| data.list[].className | String | 类名 |
| data.list[].methodName | String | 方法名 |
| data.list[].time | Double | 执行时间(毫秒) |
| data.list[].message | String | 消息 |
#### 成功响应示例
```json
{
"code": 200,
"msg": "操作成功",
"data": {
"total": 95,
"list": [
{
"id": "01pxx000000xxxx",
"className": "AccountTriggerTest",
"methodName": "testInsert",
"time": 150.5,
"message": null
}
]
}
}
```
---
### 6. 查询测试失败详情
#### 接口说明
查询指定测试结果的失败详情。
- **请求方式**GET
- **请求路径**`/apex/test/failures`
- **权限要求**`apex:test:query`
#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| testResultId | String | 是 | 测试结果 ID |
| pageNum | Integer | 否 | 页码,默认 1 |
| pageSize | Integer | 否 | 每页大小,默认 10 |
#### 请求示例
```
GET /apex/test/failures?testResultId=12345&pageNum=1&pageSize=10
```
#### 响应参数
| 参数名 | 类型 | 说明 |
|--------|------|------|
| code | Integer | 状态码200 成功,其他失败) |
| msg | String | 提示信息 |
| data | Object | 分页结果 |
| data.total | Integer | 总记录数 |
| data.list | Array | 测试失败详情列表 |
| data.list[].id | String | 测试 ID |
| data.list[].className | String | 类名 |
| data.list[].methodName | String | 方法名 |
| data.list[].message | String | 失败消息 |
| data.list[].stackTrace | String | 堆栈跟踪 |
| data.list[].time | Double | 执行时间(毫秒) |
#### 成功响应示例
```json
{
"code": 200,
"msg": "操作成功",
"data": {
"total": 5,
"list": [
{
"id": "01pxx000000xxxx",
"className": "ContactTriggerTest",
"methodName": "testUpdate",
"message": "Assertion failed",
"stackTrace": "Class.ContactTriggerTest.testUpdate: line 25, column 1",
"time": 200.0
}
]
}
}
```
---
### 7. 查询代码覆盖率
#### 接口说明
查询指定测试结果的代码覆盖率。
- **请求方式**GET
- **请求路径**`/apex/test/coverage/{testResultId}`
- **权限要求**`apex:test:query`
#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| testResultId | String | 是 | 测试结果 ID路径参数 |
| pageNum | Integer | 否 | 页码,默认 1 |
| pageSize | Integer | 否 | 每页大小,默认 10 |
#### 请求示例
```
GET /apex/test/coverage/12345?pageNum=1&pageSize=10
```
#### 响应参数
| 参数名 | 类型 | 说明 |
|--------|------|------|
| code | Integer | 状态码200 成功,其他失败) |
| msg | String | 提示信息 |
| data | Object | 分页结果 |
| data.total | Integer | 总记录数 |
| data.list | Array | 代码覆盖率列表 |
| data.list[].id | String | 类/触发器 ID |
| data.list[].name | String | 类/触发器名称 |
| data.list[].type | String | 类型Class/Trigger |
| data.list[].namespace | String | 命名空间 |
| data.list[].numLocations | Integer | 总位置数 |
| data.list[].numLocationsNotCovered | Integer | 未覆盖的位置数 |
| data.list[].coveragePercent | Double | 覆盖率百分比 |
#### 成功响应示例
```json
{
"code": 200,
"msg": "操作成功",
"data": {
"total": 50,
"list": [
{
"id": "01pxx000000xxxx",
"name": "AccountTrigger",
"type": "Trigger",
"namespace": "",
"numLocations": 100,
"numLocationsNotCovered": 15,
"coveragePercent": 85.0
}
]
}
}
```
---
### 8. 查询 Flow 覆盖率
#### 接口说明
查询指定测试结果的 Flow 覆盖率。
- **请求方式**GET
- **请求路径**`/apex/test/flow-coverage/{testResultId}`
- **权限要求**`apex:test:query`
#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| testResultId | String | 是 | 测试结果 ID路径参数 |
| pageNum | Integer | 否 | 页码,默认 1 |
| pageSize | Integer | 否 | 每页大小,默认 10 |
#### 请求示例
```
GET /apex/test/flow-coverage/12345?pageNum=1&pageSize=10
```
#### 响应参数
| 参数名 | 类型 | 说明 |
|--------|------|------|
| code | Integer | 状态码200 成功,其他失败) |
| msg | String | 提示信息 |
| data | Object | 分页结果 |
| data.total | Integer | 总记录数 |
| data.list | Array | Flow 覆盖率列表 |
| data.list[].id | String | Flow ID |
| data.list[].name | String | Flow 名称 |
| data.list[].type | String | Flow 类型 |
| data.list[].namespace | String | 命名空间 |
| data.list[].numElements | Integer | 总元素数量 |
| data.list[].numElementsCovered | Integer | 覆盖的元素数量 |
| data.list[].coveragePercent | Double | 覆盖率百分比 |
#### 成功响应示例
```json
{
"code": 200,
"msg": "操作成功",
"data": {
"total": 10,
"list": [
{
"id": "301xx000000xxxx",
"name": "Account_Automation",
"type": "AutoLaunchedFlow",
"namespace": "",
"numElements": 20,
"numElementsCovered": 18,
"coveragePercent": 90.0
}
]
}
}
```
---
## 错误码
### 统一错误码体系
| 错误码 | 说明 | 场景 |
|--------|------|------|
| APEX_TEST_001 | 参数校验失败 | 请求参数不合法 |
| APEX_TEST_002 | 连接失败 | 无法连接到 Salesforce |
| APEX_TEST_003 | 执行失败 | 测试执行过程中出错 |
| APEX_TEST_004 | 保存失败 | 保存测试结果到数据库失败 |
| APEX_TEST_005 | 查询失败 | 查询测试结果失败 |
| APEX_TEST_006 | 类不存在 | 指定的测试类不存在 |
| APEX_TEST_007 | 包不存在 | 指定的测试包不存在 |
| APEX_TEST_008 | 方法不存在 | 指定的测试方法不存在 |
| APEX_TEST_009 | 无权限 | 用户没有执行测试的权限 |
| APEX_TEST_010 | 会话过期 | Salesforce 会话已过期 |
| APEX_TEST_011 | 命名空间错误 | 指定的命名空间不存在 |
| APEX_TEST_012 | 测试运行超时 | 测试运行超时 |
| APEX_TEST_013 | 覆盖率计算失败 | 代码覆盖率计算失败 |
| APEX_TEST_014 | Flow覆盖率计算失败 | Flow 覆盖率计算失败 |
| APEX_TEST_015 | 批量插入失败 | 批量插入测试结果失败 |
| APEX_TEST_016 | 事务回滚 | 数据库事务回滚 |
| APEX_TEST_017 | 并发冲突 | 多线程并发执行冲突 |
| APEX_TEST_018 | 数据转换失败 | Salesforce 数据转换失败 |
| APEX_TEST_019 | 配置错误 | 系统配置错误 |
| APEX_TEST_020 | 未知错误 | 其他未知错误 |
### HTTP 状态码
| 状态码 | 说明 |
|--------|------|
| 200 | 请求成功 |
| 400 | 请求参数错误 |
| 401 | 未授权 |
| 403 | 禁止访问 |
| 404 | 资源不存在 |
| 500 | 服务器内部错误 |
---
## 相关文档
- [需求文档](../requirements/sub/2026-01-28-002-03-测试执行.md)
- [设计文档(重构版)](../design/2026-02-04-002-03-测试执行-设计.md)
- [决策记录(重构版)](../decisions/2026-02-04-002-03-ADR-测试执行技术选型.md)
- [变更日志(重构版)](../changelog/2026-02-04-002-03-changelog.md)
- [复盘文档(重构版)](../retros/2026-02-04-002-03-retro.md)
- [会话记录(重构版)](../sessions/2026-02-04-002-03-session.md)