114 lines
6.9 KiB
Markdown
114 lines
6.9 KiB
Markdown
# Apex 单元测试与覆盖率统计需求
|
||
|
||
## 元数据
|
||
- 需求编号:013-3
|
||
- 父需求:013
|
||
- 创建时间:2026-01-26
|
||
- 创建人:SSOT 架构师
|
||
- 状态:已完成
|
||
- 优先级:高
|
||
- 关联设计:[Apex单元测试与覆盖率统计设计](../design/2026-01-27-013-3-Apex单元测试与覆盖率统计设计.md)
|
||
- 关联代码:
|
||
- `com.sforce.soap.apex.RunTestsRequest`
|
||
- `com.sforce.soap.apex.RunTestsResult`
|
||
- `com.sforce.soap.apex.TestsNode`
|
||
- `com.sforce.soap.apex.CodeCoverageResult`
|
||
- `com.sforce.soap.apex.CodeLocation`
|
||
- `com.sforce.soap.apex.RunTestSuccess`
|
||
- `com.sforce.soap.apex.RunTestFailure`
|
||
|
||
## 需求概述
|
||
封装 Salesforce Apex 单元测试运行接口,支持同步运行测试用例(按类、按方法、按包),并获取详细的测试结果、日志 ID 和代码覆盖率数据。
|
||
|
||
## 目标
|
||
1. **灵活运行测试**:支持多种粒度的测试运行方式(所有、指定类、指定方法、指定包)。
|
||
2. **结构化结果**:将复杂的 SOAP 响应转换为清晰的 Java VO 对象。
|
||
3. **覆盖率分析**:提供精确到行级的代码覆盖率统计,支持 Class 和 Trigger。
|
||
4. **执行控制**:支持设置最大失败次数等控制参数。
|
||
|
||
## 功能需求
|
||
|
||
### 1. 运行单元测试 (Run Tests)
|
||
- **功能描述**:封装 `SoapConnection.runTests` 方法。
|
||
- **接口定义**:
|
||
```java
|
||
TestRunResult runTests(TestOptions options);
|
||
```
|
||
- **输入参数 (`TestOptions`)**:
|
||
- `boolean allTests`: 是否运行组织内的所有测试。
|
||
- `List<String> classes`: 要运行的测试类名列表(对应 SOAP `classes`)。
|
||
- `List<String> packages`: 要运行的测试包名列表(对应 SOAP `packages`)。
|
||
- `List<TestCase> tests`: 指定类和方法运行(对应 SOAP `tests` 字段,类型为 `TestsNode[]`)。
|
||
- `TestCase` VO 包含 `classId`, `className` 和 `testMethods` (List<String>)。
|
||
- `String namespace`: 指定命名空间。
|
||
- `int maxFailedTests`: 允许的最大失败测试数,超过则停止(对应 SOAP `maxFailedTests`,默认 -1 表示不限制)。
|
||
- `boolean skipCodeCoverage`: 是否跳过代码覆盖率统计(对应 SOAP `skipCodeCoverage`,默认 false)。
|
||
- **处理逻辑**:
|
||
1. 构建 `RunTestsRequest` 对象。
|
||
2. 根据 `options` 填充 `allTests`, `classes`, `packages`, `namespace`, `maxFailedTests`, `skipCodeCoverage`。
|
||
3. 如果提供了 `tests`,将其转换为 `TestsNode` 数组。
|
||
4. 调用 `connection.runTests(request)`。
|
||
|
||
### 2. 测试结果解析 (Test Result Parsing)
|
||
- **功能描述**:解析 `RunTestsResult` 对象。
|
||
- **输出对象 (`TestRunResult`)**:
|
||
- `String apexLogId`: 本次测试执行生成的调试日志 ID(对应 SOAP `apexLogId`)。
|
||
- `Summary summary`:
|
||
- `int numTestsRun`: 运行总数。
|
||
- `int numFailures`: 失败总数。
|
||
- `double totalTime`: 总耗时。
|
||
- `List<TestSuccess> successes`: 成功用例列表。
|
||
- 字段:`id`, `name` (类名), `methodName`, `time`, `namespace`, `seeAllData`。
|
||
- `List<TestFailure> failures`: 失败用例列表。
|
||
- 字段:`id`, `name`, `methodName`, `message`, `stackTrace`, `type` (异常类型), `time`, `namespace`, `seeAllData`。
|
||
|
||
### 3. 代码覆盖率统计 (Code Coverage)
|
||
- **功能描述**:解析 `RunTestsResult` 中的覆盖率数据。
|
||
- **输出对象**:包含在 `TestRunResult` 中。
|
||
- `List<CodeCoverage> coverages`:
|
||
- 字段:
|
||
- `String id`: 覆盖率记录 ID。
|
||
- `String name`: 类或触发器名称。
|
||
- `String namespace`: 命名空间。
|
||
- `String type`: 类型(Class 或 Trigger,对应 SOAP `type`)。
|
||
- `int numLocations`: 总可执行行数。
|
||
- `int numLocationsNotCovered`: 未覆盖行数。
|
||
- `List<Location> locationsNotCovered`: 未覆盖的具体位置。
|
||
- `Location`: `line` (行号), `column` (列号), `numExecutions` (执行次数), `time` (执行时间)。
|
||
- `double percentage`: 覆盖率百分比 (计算值:`(numLocations - numLocationsNotCovered) / numLocations`)。
|
||
- `List<String> warnings`: 覆盖率警告信息(对应 SOAP `codeCoverageWarnings`)。
|
||
- `List<FlowCoverage> flowCoverages`: 流程覆盖率数据(对应 SOAP `flowCoverage`)。
|
||
- `List<String> flowWarnings`: 流程覆盖率警告信息(对应 SOAP `flowCoverageWarnings`)。
|
||
|
||
## 关键代码映射 (Source Code Mapping)
|
||
|
||
### SOAP 对象映射
|
||
| 逻辑概念 | SOAP 类名 | 关键字段 |
|
||
| :--- | :--- | :--- |
|
||
| 请求参数 | `RunTestsRequest` | `allTests`, `classes`, `packages`, `tests` (`TestsNode[]`), `maxFailedTests`, `skipCodeCoverage` |
|
||
| 指定方法 | `TestsNode` | `classId`, `className`, `testMethods` |
|
||
| 响应结果 | `RunTestsResult` | `numTestsRun`, `numFailures`, `totalTime`, `apexLogId`, `successes`, `failures`, `codeCoverage`, `codeCoverageWarnings`, `flowCoverage`, `flowCoverageWarnings` |
|
||
| 成功详情 | `RunTestSuccess` | `id`, `name`, `methodName`, `time`, `namespace`, `seeAllData` |
|
||
| 失败详情 | `RunTestFailure` | `id`, `name`, `methodName`, `message`, `stackTrace`, `type`, `time`, `namespace`, `seeAllData` |
|
||
| 覆盖率 | `CodeCoverageResult` | `id`, `name`, `namespace`, `type`, `numLocations`, `numLocationsNotCovered`, `locationsNotCovered` |
|
||
| 代码位置 | `CodeLocation` | `line`, `column`, `numExecutions`, `time` |
|
||
|
||
## 验证与测试
|
||
1. **全量测试**:设置 `allTests=true`,验证能触发所有测试并返回统计。
|
||
2. **指定类测试**:设置 `classes=['MyTest']`,验证只运行指定类。
|
||
3. **指定方法测试**:设置 `tests=[{className='MyTest', testMethods=['testMethod1']}]`,验证只运行指定方法。
|
||
4. **失败处理**:运行一个必定失败的测试,验证 `failures` 列表中包含正确的 `message` 和 `stackTrace`。
|
||
5. **覆盖率验证**:运行测试后,检查返回的 `coverages` 列表,验证 `locationsNotCovered` 包含预期的未覆盖行号。
|
||
6. **日志 ID**:验证返回的 `apexLogId` 不为空(当有日志生成时)。
|
||
|
||
## 非功能需求
|
||
- **性能优化**:覆盖率数据(`locationsNotCovered`)可能非常大,建议在 `TestOptions` 中增加 `boolean skipCoverage` 选项(虽然 SOAP API 不直接支持跳过,但可以在客户端解析时选择性忽略)。
|
||
- **超时处理**:由于 `runTests` 是同步调用,对于大量测试可能会超时,需在文档中注明建议对于大规模测试使用异步 API (7.0 以后版本考虑,当前需求仅关注同步)。
|
||
|
||
## 相关文档
|
||
- [设计文档](../design/2026-01-27-013-3-Apex单元测试与覆盖率统计设计.md)
|
||
- [决策记录](../decisions/adr/2026-01-27-013-3-ADR-Apex测试执行与覆盖率方案.md)
|
||
- [提示词文档](../prompts/2026-01-27-013-3-prompt-Apex单元测试与覆盖率统计.md)
|
||
- [变更日志](../changelog/2026-01-27-013-3-changelog.md)
|
||
- [会话记录](../sessions/2026-01-27-013-3-session.md)
|