test-spec.md 13 KB

单测 Spec — 采购仓储低代码应用配置落地

status: apply created: 2026-07-03

0. 测试原则

  • 增量验证:每轮只验证本轮变更,但必须复用 spec.mdtasks.mdexecution-log.md
  • 低代码优先:本变更不新增采购仓储专用服务类,第一阶段主要验证 Flyway SQL、运行配置 JSON 和构建。
  • 高风险动作单独验证:后续涉及数量台账动作时必须补动作执行或端到端验收记录。

1. 测试框架

项目
JUnit 版本 JUnit 5(后续动作服务单测使用)
Mock 框架 Mockito / 本地 fake(按既有测试情况选择)
前端验证 pnpm --dir forge-admin-ui build
后端验证 Maven 插件编译 / 定向单测

2. 覆盖范围

P0 — 第一阶段基础资产

范围 场景 预期结果
Flyway SQL 运行表 DDL 表包含租户、审计、逻辑删除字段,脚本可重复执行
Flyway SQL seed 防重复 所有 INSERTNOT EXISTS 或唯一键保护
运行配置 ai_crud_config JSON api_config 指向 /ai/crud/{configKey}publish_status=PUBLISHED
应用入口 ai_business_app entry_mode=RUNTIMEconfig_key 有对应配置

P1 — 主子表与选择器

范围 场景 预期结果
页面协议 master-detail-crud 主子表配置能生成 masterDetailConfig
选择器 多字段搜索/动态过滤 物料、库存候选能按配置查询

P2 — 流程动作与数量台账

范围 场景 预期结果
动作配置 FOREACH + QUANTITY 每行明细写入稳定幂等键
流程回调 审批通过/驳回 正确执行入库、扣减、释放、转移

不测试

  • 第一阶段不做真实 MySQL/Redis 联调,除非本地服务已可用。
  • 第一阶段不做像素级 UI 自动截图,先以配置结构和构建为准。

3. 执行计划

  • Step 1: 读取 code-copilot/rules/automated-testing-standard.md
  • Step 2: git diff --check
  • Step 3: Flyway placeholder 扫描:rg -n '\$\{[^}]+\}' forge-server/db/migration
  • Step 4: 后端插件编译。
  • Step 5: 前端构建。
  • Step 6: 如新增 Java 动作逻辑,补定向单测并记录 Tests run

4. 历史验证基线

时间 范围 命令 结果 备注
2026-07-03 lowcode-business-transaction-closure Maven 定向单测、后端编译、前端构建 通过 已具备平台底座

5. 本轮增量验证

时间 变更范围 必跑项 实际命令 结果 跳过/警告
2026-07-03 Phase 1/2 SQL 与配置 空白检查 git diff --no-index --check /dev/null forge-server/db/migration/V1.0.90__seed_procurement_warehouse_lowcode_app.sql 通过,无空白错误输出 退出码 1 为 /dev/null 对比差异语义,不代表检查失败
2026-07-03 Phase 1/2 SQL 与配置 Flyway placeholder 扫描 rg -n '\$\{[^}]+\}' forge-server/db/migration/V1.0.90__seed_procurement_warehouse_lowcode_app.sql 通过,无输出 选择器表达式使用 CONCAT('$', '{formData.xxx}') 避免 Flyway 占位符
2026-07-03 Phase 1/2 SQL 与配置 SQL 轻量结构检查 `node -e "const fs=require('fs'); const s=fs.readFileSync(process.argv[1],'utf8'); const q=(s.match(/[']/g) []).length; const l=(s.match(/\(/g)
2026-07-03 后端运行态解析链路 generator 插件编译 JAVA_HOME=/opt/homebrew/Cellar/openjdk@17/17.0.13/libexec/openjdk.jdk/Contents/Home PATH=/opt/homebrew/Cellar/openjdk@17/17.0.13/libexec/openjdk.jdk/Contents/Home/bin:$PATH mvn -pl forge-framework/forge-plugin-parent/forge-plugin-generator -am compile -DskipTests 通过,BUILD SUCCESS 既有 deprecated/unchecked 编译警告
2026-07-03 前端运行态消费链路 前端构建 source ~/.nvm/nvm.sh && nvm use v20.19.0 && NODE_OPTIONS=--max-old-space-size=8192 pnpm --dir forge-admin-ui build 通过,built in 1m 39s 既有 Vite chunk 提示、CSS // 注释 warning、UserSelectModal 命名冲突提示
2026-07-03 Phase 3 流程与数量动作 空白检查 git diff --no-index --check /dev/null forge-server/db/migration/V1.0.91__seed_procurement_warehouse_flow_actions.sql 通过,无空白错误输出 退出码 1 为 /dev/null 对比差异语义,不代表检查失败
2026-07-03 Phase 3 流程与数量动作 Flyway placeholder 扫描 rg -n '\$\{[^}]+\}' forge-server/db/migration/V1.0.91__seed_procurement_warehouse_flow_actions.sql 通过,无输出 动作表达式使用 CONCAT('$', '{...}')
2026-07-03 Phase 3 流程与数量动作 SQL 轻量结构检查 `node -e "const fs=require('fs'); const s=fs.readFileSync(process.argv[1],'utf8'); const q=(s.match(/[']/g) []).length; const l=(s.match(/\(/g)
2026-07-03 Phase 3 后端运行态解析链路 generator 插件编译 JAVA_HOME=/opt/homebrew/Cellar/openjdk@17/17.0.13/libexec/openjdk.jdk/Contents/Home PATH=/opt/homebrew/Cellar/openjdk@17/17.0.13/libexec/openjdk.jdk/Contents/Home/bin:$PATH mvn -pl forge-framework/forge-plugin-parent/forge-plugin-generator -am compile -DskipTests 通过,BUILD SUCCESS 既有 deprecated/unchecked 编译警告
2026-07-03 Phase 3 前端运行态消费链路 前端构建 source ~/.nvm/nvm.sh && nvm use v20.19.0 && NODE_OPTIONS=--max-old-space-size=8192 pnpm --dir forge-admin-ui build 通过,built in 2m 20s 既有 Vite chunk 提示、CSS // 注释 warning、UserSelectModal 命名冲突提示
2026-07-03 Phase 4 详情区块与演示数据 空白检查 git diff --no-index --check /dev/null forge-server/db/migration/V1.0.92__seed_procurement_warehouse_detail_panels_demo_data.sql 通过,无空白错误输出 退出码 1 为 /dev/null 对比差异语义,不代表检查失败
2026-07-03 Phase 4 详情区块与演示数据 Flyway placeholder 扫描 rg -n '\$\{[^}]+\}' forge-server/db/migration/V1.0.92__seed_procurement_warehouse_detail_panels_demo_data.sql 通过,无输出 面板表达式使用 CONCAT('$', '{row.id}')
2026-07-03 Phase 4 详情区块与演示数据 SQL 轻量结构检查 `node -e "const fs=require('fs'); const s=fs.readFileSync(process.argv[1],'utf8'); const q=(s.match(/[']/g) []).length; const l=(s.match(/\(/g)
2026-07-03 Phase 5 原型对照 文档检查 `rg -n "采购管理 仓储管理 供应商管理
2026-07-03 用户反馈修复 代码空白检查 git diff --check -- <本轮相关前后端文件> 通过,无输出 仅检查本轮相关文件,避免混入其它未提交变更
2026-07-03 用户反馈修复 V1.0.93 空白检查 git diff --no-index --check /dev/null forge-server/db/migration/V1.0.93__fix_procurement_warehouse_lowcode_runtime_config.sql 通过,无空白错误输出 退出码 1 为 /dev/null 对比差异语义,不代表检查失败
2026-07-03 用户反馈修复 Flyway placeholder 扫描 rg -n '\$\{[^}]+\}' forge-server/db/migration/V1.0.93__fix_procurement_warehouse_lowcode_runtime_config.sql 通过,无输出 编码规则模板使用 CONCAT('$', '{...}')
2026-07-03 用户反馈修复 SQL 轻量结构检查 `node -e "const fs=require('fs'); const s=fs.readFileSync(process.argv[1],'utf8'); const q=(s.match(/[']/g) []).length; const l=(s.match(/\(/g)
2026-07-03 用户反馈修复 后端编译 JAVA_HOME=/opt/homebrew/Cellar/openjdk@17/17.0.13/libexec/openjdk.jdk/Contents/Home PATH=/opt/homebrew/Cellar/openjdk@17/17.0.13/libexec/openjdk.jdk/Contents/Home/bin:$PATH mvn -pl forge-framework/forge-plugin-parent/forge-plugin-generator -am compile -DskipTests 通过,BUILD SUCCESS,总耗时 24.179 s 既有 deprecated/unchecked 编译警告
2026-07-03 用户反馈修复 前端构建 source ~/.nvm/nvm.sh && nvm use v20.19.0 && NODE_OPTIONS=--max-old-space-size=8192 pnpm --dir forge-admin-ui build 通过,built in 2m 16s 既有 UserSelectModal 命名冲突、Vite chunk、CSS // 注释 warning
2026-07-03 物料新增编号为空修复 定向单测 JAVA_HOME=/opt/homebrew/Cellar/openjdk@17/17.0.13/libexec/openjdk.jdk/Contents/Home PATH=/opt/homebrew/Cellar/openjdk@17/17.0.13/libexec/openjdk.jdk/Contents/Home/bin:$PATH mvn -Penable-tests -pl forge-framework/forge-plugin-parent/forge-plugin-generator -Dtest=DynamicCrudServiceAutoGenerationTest test 通过,Tests run: 3, Failures: 0, Errors: 0, Skipped: 0 首次使用 Mockito mock 时因 ByteBuddy agent 自附加失败,已改为轻量 fake 后通过
2026-07-03 物料新增编号为空修复 后端空白检查与编译 git diff --check -- DynamicCrudService.java DynamicCrudServiceAutoGenerationTest.javaJAVA_HOME=/opt/homebrew/Cellar/openjdk@17/17.0.13/libexec/openjdk.jdk/Contents/Home PATH=/opt/homebrew/Cellar/openjdk@17/17.0.13/libexec/openjdk.jdk/Contents/Home/bin:$PATH mvn -pl forge-framework/forge-plugin-parent/forge-plugin-generator -am compile -DskipTests 通过,BUILD SUCCESS,总耗时 12.886 s 既有 deprecated/unchecked 编译警告
2026-07-03 二次反馈修复 代码空白检查 git diff --check -- BusinessFieldPropertyPanel.vue ForgePropertyPanel.vue BusinessFormDesigner.vue BusinessObjectDesignerShell.vue ChildTableEditor.vue BusinessObjectDesignerService.java V1.0.94__fix_procurement_warehouse_designer_flow_relation_config.sql 通过,无输出 仅检查本轮相关文件
2026-07-03 二次反馈修复 V1.0.94 Flyway placeholder 扫描 rg -n '\$\{[^}]+\}' forge-server/db/migration/V1.0.94__fix_procurement_warehouse_designer_flow_relation_config.sql 通过,无输出 无 Flyway 占位符风险
2026-07-03 二次反馈修复 V1.0.94 SQL 轻量结构检查 `node -e "const fs=require('fs'); const s=fs.readFileSync(process.argv[1],'utf8'); const q=(s.match(/[']/g) []).length; const l=(s.match(/\(/g)
2026-07-03 二次反馈修复 后端编译 JAVA_HOME=/opt/homebrew/Cellar/openjdk@17/17.0.13/libexec/openjdk.jdk/Contents/Home PATH=/opt/homebrew/Cellar/openjdk@17/17.0.13/libexec/openjdk.jdk/Contents/Home/bin:$PATH mvn -pl forge-framework/forge-plugin-parent/forge-plugin-generator -am compile -DskipTests 通过,BUILD SUCCESS,总耗时 14.202 s 既有 deprecated/unchecked 编译警告
2026-07-03 二次反馈修复 前端构建 source ~/.nvm/nvm.sh && nvm use v20.19.0 && NODE_OPTIONS=--max-old-space-size=8192 pnpm --dir forge-admin-ui build 通过,built in 1m 54s 既有 UserSelectModal 命名冲突、Vite dynamic/static import chunk 提示、CSS // 注释 warning

6. 执行证据

  • execution-log.md:记录每轮命令、结果、警告和跳过项。
  • 关键接口:/ai/crud/{configKey}/ai/business/action/execute/ai/business/quantity/query/*
  • 关键数据库检查:ai_crud_configai_business_appai_lowcode_modelpw_* 运行表。
  • 服务启动与停止:如启动本地服务,必须记录 PID 和清理情况。