docs: plan AI test one-click workflow
This commit is contained in:
@@ -0,0 +1,233 @@
|
||||
# AI Test One-Click Workflow Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** 在“项目与增量”Tab 内一键完成增量分析、单测生成、Maven/JaCoCo 验证与覆盖率展示,并在首次使用时自动发现和保存 JDK 8、Maven 与 CodeFree 配置。
|
||||
|
||||
**Architecture:** 新增独立的工具链发现器,只负责从保存值、环境、运行时和 Maven 输出解析路径;`AiTestPane` 通过单个后台任务串联现有 `analyze` 与 `generateAndVerify`,领域工作流保持不变。界面通过稳定的控件 ID 和状态转换测试验证第一 Tab 操作与结果自动定位。
|
||||
|
||||
**Tech Stack:** Java 17 编译、目标业务 JDK 8、JavaFX 17、Maven 3.8.6、JUnit 5、Mockito、CodeFree CLI 0.3.6、JaCoCo。
|
||||
|
||||
## Global Constraints
|
||||
|
||||
- 不使用子代理,当前会话单线程实施。
|
||||
- 用户保存配置优先,自动探测仅补齐空值或不存在的首次配置。
|
||||
- Windows 兜底路径只有真实存在时才使用;macOS/Linux 不写入 Windows 路径。
|
||||
- 不修改 CodeFree CLI 协议、质量规范格式、合并审核规则和手机 UI 自动化插件。
|
||||
- 保留 `master...DEV_1156339215001460262` 与最新异步请求防覆盖逻辑。
|
||||
- 不暂存或修改现有未跟踪审计文件、截图目录和 SQL 文件。
|
||||
|
||||
---
|
||||
|
||||
### Task 1: 默认工具链自动发现
|
||||
|
||||
**Files:**
|
||||
- Create: `src/main/java/com/example/workutils/biz/aitest/config/ToolchainSettingsDetector.java`
|
||||
- Modify: `src/main/java/com/example/workutils/biz/aitest/config/AiTestSettingsService.java`
|
||||
- Test: `src/test/java/com/example/workutils/biz/aitest/config/ToolchainSettingsDetectorTest.java`
|
||||
- Test: `src/test/java/com/example/workutils/biz/aitest/config/AiTestSettingsServiceTest.java`
|
||||
|
||||
**Interfaces:**
|
||||
- Produces: `AiTestSettings ToolchainSettingsDetector.complete(AiTestSettings saved)`。
|
||||
- Consumes: 环境变量读取函数、系统属性读取函数、文件存在性函数,以及返回 `mvn -version` 输出的函数,均通过构造参数注入以便测试。
|
||||
- `AiTestSettingsService.load()` 在文件不存在时调用发现器;配置文件存在时只补齐空路径,不覆盖有效保存值。
|
||||
|
||||
- [ ] **Step 1: 写失败测试**
|
||||
|
||||
```java
|
||||
@Test
|
||||
void discoversJdkRootFromJavaHomeJreAndParsesMavenHome() {
|
||||
ToolchainSettingsDetector detector = fixture(
|
||||
Map.of(), Map.of("java.home", "C:/Program Files/Java/jdk-1.8/jre"),
|
||||
"Apache Maven 3.8.6\nMaven home: D:/bestpay-maven/apache-maven-3.8.6");
|
||||
AiTestSettings result = detector.complete(AiTestSettings.defaults());
|
||||
assertEquals(Path.of("C:/Program Files/Java/jdk-1.8"), result.jdk8Home());
|
||||
assertEquals(Path.of("D:/bestpay-maven/apache-maven-3.8.6"), result.mavenHome());
|
||||
}
|
||||
```
|
||||
|
||||
同时覆盖:保存值优先、`JAVA_HOME`、`MAVEN_HOME`、`M2_HOME`、非 Windows 不使用 Windows 兜底、探测值被 `AiTestSettingsService` 保存。
|
||||
|
||||
- [ ] **Step 2: 运行测试并确认 RED**
|
||||
|
||||
Run: `$env:JAVA_HOME='C:\Program Files\Java\jdk-17'; mvn -Dtest=ToolchainSettingsDetectorTest,AiTestSettingsServiceTest test`
|
||||
|
||||
Expected: FAIL,因为 `ToolchainSettingsDetector` 尚不存在且服务不会自动保存探测结果。
|
||||
|
||||
- [ ] **Step 3: 实现最小发现器**
|
||||
|
||||
```java
|
||||
public AiTestSettings complete(AiTestSettings saved) {
|
||||
Path jdk = usable(saved.jdk8Home()) ? saved.jdk8Home() : detectJdk8();
|
||||
Path maven = usable(saved.mavenHome()) ? saved.mavenHome() : detectMaven();
|
||||
return new AiTestSettings(jdk, maven, saved.codeFreeCommand(), saved.coverageTarget(),
|
||||
saved.maxRepairRounds(), saved.codeFreeTimeout(), saved.mavenTimeout());
|
||||
}
|
||||
```
|
||||
|
||||
JDK 发现顺序为 `JAVA_HOME`、`java.home`、存在的 Windows 兜底;Maven 顺序为 `MAVEN_HOME`、`M2_HOME`、`mvn -version` 的 `Maven home:`、存在的 Windows 兜底。
|
||||
|
||||
- [ ] **Step 4: 运行聚焦测试并确认 GREEN**
|
||||
|
||||
Run: `$env:JAVA_HOME='C:\Program Files\Java\jdk-17'; mvn -Dtest=ToolchainSettingsDetectorTest,AiTestSettingsServiceTest test`
|
||||
|
||||
Expected: 所有配置探测测试通过。
|
||||
|
||||
- [ ] **Step 5: 提交**
|
||||
|
||||
```powershell
|
||||
git add src/main/java/com/example/workutils/biz/aitest/config/ToolchainSettingsDetector.java src/main/java/com/example/workutils/biz/aitest/config/AiTestSettingsService.java src/test/java/com/example/workutils/biz/aitest/config/ToolchainSettingsDetectorTest.java src/test/java/com/example/workutils/biz/aitest/config/AiTestSettingsServiceTest.java
|
||||
git commit -m "feat: discover default AI test toolchain"
|
||||
```
|
||||
|
||||
### Task 2: 一键协调执行链
|
||||
|
||||
**Files:**
|
||||
- Create: `src/main/java/com/example/workutils/biz/aitest/application/AiTestOneClickRunner.java`
|
||||
- Modify: `src/main/java/com/example/workutils/biz/aitest/AiTestPlugin.java`
|
||||
- Modify: `src/main/java/com/example/workutils/biz/aitest/AiTestPane.java`
|
||||
- Test: `src/test/java/com/example/workutils/biz/aitest/application/AiTestOneClickRunnerTest.java`
|
||||
|
||||
**Interfaces:**
|
||||
- Produces: `AiTestRun AiTestOneClickRunner.run(AiTestRequest request, Consumer<AiTestProgress> progress)`。
|
||||
- Consumes: `AiTestWorkflow.analyze` 与 `AiTestWorkflow.generateAndVerify`。
|
||||
- 当分析结果不是 `ANALYZED` 时原样返回且不调用生成;分析成功时继续生成验证。
|
||||
|
||||
- [ ] **Step 1: 写失败测试**
|
||||
|
||||
```java
|
||||
@Test
|
||||
void generatesAndVerifiesAfterSuccessfulAnalysis() {
|
||||
when(workflow.analyze(request, progress)).thenReturn(analyzed);
|
||||
when(workflow.generateAndVerify(analyzed, progress)).thenReturn(ready);
|
||||
assertSame(ready, runner.run(request, progress));
|
||||
verify(workflow).generateAndVerify(analyzed, progress);
|
||||
}
|
||||
|
||||
@Test
|
||||
void stopsWhenAnalysisFails() {
|
||||
when(workflow.analyze(request, progress)).thenReturn(failed);
|
||||
assertSame(failed, runner.run(request, progress));
|
||||
verify(workflow, never()).generateAndVerify(any(), any());
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 运行测试并确认 RED**
|
||||
|
||||
Run: `$env:JAVA_HOME='C:\Program Files\Java\jdk-17'; mvn -Dtest=AiTestOneClickRunnerTest test`
|
||||
|
||||
Expected: FAIL,因为协调器尚不存在。
|
||||
|
||||
- [ ] **Step 3: 实现最小协调器并注入界面**
|
||||
|
||||
```java
|
||||
public AiTestRun run(AiTestRequest request, Consumer<AiTestProgress> progress) {
|
||||
AiTestRun analyzed = workflow.analyze(request, progress);
|
||||
return analyzed.state() == AiTestRunState.ANALYZED
|
||||
? workflow.generateAndVerify(analyzed, progress)
|
||||
: analyzed;
|
||||
}
|
||||
```
|
||||
|
||||
`AiTestPane` 一键操作必须只调用一次 `runAsync`,确保 busy/progress 在完整链路结束后才复位。
|
||||
|
||||
- [ ] **Step 4: 运行测试并确认 GREEN**
|
||||
|
||||
Run: `$env:JAVA_HOME='C:\Program Files\Java\jdk-17'; mvn -Dtest=AiTestOneClickRunnerTest,AiTestWorkflowTest test`
|
||||
|
||||
Expected: 协调器与既有工作流测试通过。
|
||||
|
||||
- [ ] **Step 5: 提交**
|
||||
|
||||
```powershell
|
||||
git add src/main/java/com/example/workutils/biz/aitest/application/AiTestOneClickRunner.java src/main/java/com/example/workutils/biz/aitest/AiTestPlugin.java src/main/java/com/example/workutils/biz/aitest/AiTestPane.java src/test/java/com/example/workutils/biz/aitest/application/AiTestOneClickRunnerTest.java
|
||||
git commit -m "feat: run AI test generation and coverage in one action"
|
||||
```
|
||||
|
||||
### Task 3: 第一 Tab 操作与结果自动定位
|
||||
|
||||
**Files:**
|
||||
- Modify: `src/main/java/com/example/workutils/biz/aitest/AiTestPane.java`
|
||||
- Modify: `src/test/java/com/example/workutils/biz/aitest/AiTestPaneArchitectureTest.java`
|
||||
|
||||
**Interfaces:**
|
||||
- 主按钮 ID:`generate-and-cover-action`,文本“生成单测并分析覆盖率”。
|
||||
- 次按钮 ID:`analyze-only-action`,文本“仅分析增量”。
|
||||
- 主 TabPane ID:`ai-test-main-tabs`;结果 TabPane ID:`ai-test-result-tabs`。
|
||||
- 成功选择主 Tab“结果与合并”和内层 Tab“覆盖率”;失败选择内层 Tab“运行日志”。
|
||||
|
||||
- [ ] **Step 1: 写失败的 JavaFX 结构/状态测试**
|
||||
|
||||
```java
|
||||
assertEquals("项目与增量", mainTabs.getSelectionModel().getSelectedItem().getText());
|
||||
assertNotNull(pane.lookup("#generate-and-cover-action"));
|
||||
assertNotNull(pane.lookup("#analyze-only-action"));
|
||||
assertFalse(toolchainTab.isSelected());
|
||||
```
|
||||
|
||||
增加可直接调用的包内结果呈现测试入口或提取无状态 `AiTestResultSelection`,分别断言 `READY_FOR_REVIEW` 选覆盖率、`FAILED` 选运行日志。
|
||||
|
||||
- [ ] **Step 2: 运行测试并确认 RED**
|
||||
|
||||
Run: `$env:JAVA_HOME='C:\Program Files\Java\jdk-17'; mvn -Dtest=AiTestPaneArchitectureTest,AiTestResultSelectionTest test`
|
||||
|
||||
Expected: FAIL,因为主操作仍位于结果 Tab 且没有结果选择策略。
|
||||
|
||||
- [ ] **Step 3: 实现第一 Tab 操作区与选择策略**
|
||||
|
||||
```java
|
||||
HBox projectActions = new HBox(10, generateAndCoverButton, analyzeOnlyButton);
|
||||
VBox projectPage = page(selection, projectActions);
|
||||
```
|
||||
|
||||
删除结果 Tab 中重复的“分析增量/生成并验证”操作,只保留执行中的“取消”。工具链异常时保持当前结果并提示进入“工具链”;正常成功或失败按状态切换结果子 Tab。
|
||||
|
||||
- [ ] **Step 4: 运行 UI 与插件聚焦测试并确认 GREEN**
|
||||
|
||||
Run: `$env:JAVA_HOME='C:\Program Files\Java\jdk-17'; mvn -Dtest=AiTestPaneArchitectureTest,AiTestResultSelectionTest,AiTestPluginTest test`
|
||||
|
||||
Expected: 第一 Tab 操作、默认选择及结果定位测试全部通过。
|
||||
|
||||
- [ ] **Step 5: 提交**
|
||||
|
||||
```powershell
|
||||
git add src/main/java/com/example/workutils/biz/aitest/AiTestPane.java src/test/java/com/example/workutils/biz/aitest/AiTestPaneArchitectureTest.java src/main/java/com/example/workutils/biz/aitest/ui/AiTestResultSelection.java src/test/java/com/example/workutils/biz/aitest/ui/AiTestResultSelectionTest.java
|
||||
git commit -m "feat: expose one-click AI test workflow on project tab"
|
||||
```
|
||||
|
||||
### Task 4: 真实项目回归与发布验证
|
||||
|
||||
**Files:**
|
||||
- Modify only if a regression exposes a defect in files from Tasks 1-3.
|
||||
- Verify: `src/test/java/com/example/workutils/biz/aitest/project/FtLoanCapitalCoreRegressionTest.java`
|
||||
|
||||
**Interfaces:**
|
||||
- `master...DEV_1156339215001460262` 必须继续定位 `ft-loancapital-core-start` 并分析显式目标引用。
|
||||
- 打包产物:`target/workutils-1.0.1-SNAPSHOT.jar`。
|
||||
|
||||
- [ ] **Step 1: 运行真实项目和 AI 插件测试**
|
||||
|
||||
Run: `$env:JAVA_HOME='C:\Program Files\Java\jdk-17'; mvn -Dtest='com.example.workutils.biz.aitest.**,FtLoanCapitalCoreRegressionTest' test`
|
||||
|
||||
Expected: AI 插件测试与真实项目回归全部通过。
|
||||
|
||||
- [ ] **Step 2: 运行全量测试**
|
||||
|
||||
Run: `$env:JAVA_HOME='C:\Program Files\Java\jdk-17'; mvn test`
|
||||
|
||||
Expected: 0 failures、0 errors;仅允许既有 GUI 环境跳过项。
|
||||
|
||||
- [ ] **Step 3: 打包与差异检查**
|
||||
|
||||
Run: `$env:JAVA_HOME='C:\Program Files\Java\jdk-17'; mvn -DskipTests package; git diff --check; git status --short`
|
||||
|
||||
Expected: BUILD SUCCESS、`git diff --check` 无输出,用户未跟踪文件保持未暂存。
|
||||
|
||||
- [ ] **Step 4: 提交验证阶段必要修复(如有)**
|
||||
|
||||
```powershell
|
||||
git add -- <only-files-changed-by-this-plan>
|
||||
git commit -m "fix: complete AI test one-click regression"
|
||||
```
|
||||
|
||||
若没有必要修复则不创建空提交。
|
||||
Reference in New Issue
Block a user