mcpField
C
camunda-process-test

camunda-process-test

github.com/camunda测试与质量26123 次安装今天更新
代码仓库

关于 camunda-process-test

camunda-process-test 是面向 Camunda 8.8+ 的流程测试技能,供使用 Maven 和 Java 的开发者编写并运行测试。它通过规划测试片段覆盖 BPMN 元素与路由,并以覆盖率报告检查遗漏。

主要功能

  1. 01规划覆盖 BPMN 元素的最少测试片段
  2. 02编写指令式或 Java 测试
  3. 03运行 Maven 测试
  4. 04检查元素及序列流覆盖率
  5. 05识别冗余场景与覆盖缺口

适用场景

  1. 01验证 BPMN 网关分支路由
  2. 02覆盖 DMN 规则和边界事件
  3. 03为流程补充缺失测试场景
  4. 04根据覆盖报告定位未覆盖元素

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/camunda/skills --skill camunda-process-test

安装后在 Claude Code 中输入/camunda-process-test确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

portability.json
references/
authoring.md
ci.md
connectors-runtime.md
coverage-strategy.md
evaluation.md
run-and-diagnose.md
setup.md
test-context.md
troubleshooting.md

详细介绍

Camunda 流程测试

工作流技能:规划测试片段、编写场景、运行 Maven 测试命令,并弥补覆盖率缺口。

不要用于:

不要使用此技能编写 BPMN、DMN、FEEL 或表单,部署到生产集群,或测试 UI 行为。请将这些任务交给 camunda-bpmn、camunda-dmn、camunda-feel、camunda-forms、camunda-process-mgmt 或相关的 UI 测试框架。

为 Camunda 8.8+ 编写并运行 Camunda Process Test 套件,以最少的测试片段实现 100% BPMN 元素覆盖率。测试断言仅限于可达性和路由——CPT 验证引擎是否经过了正确的元素,而非服务任务或外部系统产生的数据值。

前置条件

  • Java 21+、Maven(或 ./mvnw)、Docker 运行时(OrbStack、Docker Desktop 或 Rancher Desktop)——请参阅 references/setup.md
  • 对于 Java 备用测试套件,测试类路径中需包含 camunda-process-test-spring 8.8+;基于指令的 .test.json 格式和仅限 8.9 的 API 需要 8.9+
  • 可正常工作的 BPMN 文件(通过 lint 检查——请参阅 camunda-bpmn)。BPMN 引用的 DMN 和表单文件也必须存在。

对于 Node.js 布局,请设置 NODE_RESOURCE_DIR,并从生成的 test/ 目录运行 Maven,具体说明见 references/setup.md。以下 Maven 命令与 Shell 无关;Node.js POM 会读取此环境变量,标准 Java 布局则不需要该变量。

交叉参考

  • camunda-bpmn:编写场景前,对待测流程运行 c8ctl bpmn lint——lint 未通过会导致部署时 @TestDeployment 失败。
  • camunda-feel:网关条件或 DMN 条目不明确时使用;FEEL 语义决定哪个测试片段会命中哪个分支。
  • camunda-dmn:待测单元为 DMN 决策时使用——CPT 通过调用业务规则任务来测试它;搭配 npx dmnlint 进行结构检查。
  • camunda-job-workers:待测单元为服务任务的处理程序代码时使用——CPT 驱动 BPMN 可达性;工作器单元测试则验证处理程序行为。
  • camunda-connectors-development:待测单元为自定义连接器时使用——CPT 从 BPMN 侧测试连接器;SDK 侧测试则直接覆盖连接器类。
  • camunda-ai-agents:测试 AI Agent 子流程时使用——它会驱动 BPMN 图形,而 COMPLETE_JOB_AD_HOC_SUB_PROCESS 和 context.when().then() 会对此进行编排。
  • camunda-process-mgmt:CPT 在嵌入式 Zeebe 引擎上运行——不使用 c8ctl 管理的集群或任何配置文件。没有任何 c8ctl 调用会部署待测流程。

范围边界

  • 范围内:BPMN 可达性(每个元素至少访问一次)、网关分支选择、DMN 规则选择、错误边界事件触发、定时器/升级边界事件触发、结束事件选择。
  • 范围外:断言服务任务产生的数据值、外部系统负载、UI 行为、Agent/大模型输出。除非变量是你同时测试的下游网关的 FEEL 输入,否则不要对服务任务的输出编写 ASSERT_VARIABLE 指令。

工作流

1. 检测

按优先顺序查找待测试的 BPMN:

  1. src/main/resources/processes/
  2. src/main/resources/bpmn/
  3. 项目构建配置中声明的资源目录(例如,Node.js 项目可能将资源放在 resources/ 中,而将测试框架放在 test/ 中)。

跳过 target/、node_modules/、.git/、build/。如果匹配到多个文件,请列出这些文件并询问要针对哪个文件。

检查 pom.xml(或 test/pom.xml)中是否有 camunda-process-test-spring。如果没有,请转到第 2 步。

如果已有场景,请先运行漂移检查,再编辑测试:

git diff <base-branch>...HEAD -- <bpmn-path>

将 PR 的基分支或仓库默认分支用作 <base-branch>(通常是 main)。

然后对当前测试套件的缺口进行分类:

  • 损坏:场景引用的 elementId 或 processDefinitionId 已不存在。
  • 过时:ID 仍然存在,但驱动分支的变量或假设与网关/DMN 行为不再匹配。
  • 缺失:新分支、边界事件或结束事件没有对应的片段覆盖。

按以下顺序修复:损坏 → 过时 → 缺失,然后运行 mvn test 并继续进行覆盖验证。

2. 设置(仅在缺少时)

遵循 references/setup.md:运行就绪预检(Java、Maven/wrapper、Docker),添加 CPT 依赖,为 CPT 8.9+ 创建脚手架文件 src/test/java/io/camunda/tests/ProcessTest.java 和目录 src/test/resources/scenarios/,或为 CPT 8.8 使用 Java 后备方案。运行 mvn test-compile 确认。

3. 规划片段(集合覆盖,而非逐元素规划)

在编写任何内容之前,先规划最少数量的片段。应用 references/coverage-strategy.md:

  1. 解析 BPMN:processId、元素 ID 和类型、网关的出流及条件、错误/定时器/升级边界、结束事件、调用的 DMN 决策(<zeebe:calledDecision decisionId="…">)以及其中的 DMN 规则。
  2. 枚举候选片段。 为每个网关分支、DMN 规则、边界事件和备用结束事件定义一个最小候选片段,其根节点为最近的上游决策点。对于每个候选片段,通过从根节点开始沿 BPMN 向前遍历目标分支,直到下一个汇合点或结束事件,静态预测其完整的已访问元素和顺序流集合。
  3. 贪心集合覆盖。 不断选取预测集合能覆盖最多未覆盖 ID 的候选片段。若并列,则优先选择路径最短的片段(编写成本最低)。当并集覆盖所有 ID 时停止。
  4. 诊断隔离例外(可选)。 如果两个选中的片段共享同一个根节点,但触发了不同的故障模式(例如,一个触发边界事件,另一个正常完成用户任务),则保留两者,以便故障能明确指向单一原因。仅在用户正在调试特定区域时应用;默认使用纯集合覆盖。
  5. 将片段计划打印为表格:segment name | root | predicted ids covered | end condition。编写时严格按照此列表实现,不添加之后可能会被去重的推测性场景。

**示例:**对于包含 approved 和 rejected 流的网关,为每个流规划一个片段,预测到下一个汇合点期间访问的 ID,并保留覆盖这两个分支及共享结束路径所需的最少片段。

4. 编写

对于 CPT 8.9 及更高版本,按照 references/authoring.md,在 src/test/resources/scenarios/<processId>.test.json 中编写一条条目。对于 CPT 8.8,请使用该参考文档中描述的 Java 备用方案,而不是 .test.json。命名格式:"<who/what> — <outcome>"。断言:对分段必须经过的元素使用 ASSERT_ELEMENT_INSTANCES,仅当分段运行至结束事件时使用 ASSERT_PROCESS_INSTANCE。

对于 CPT 8.9 及更高版本,仅当分段需要模拟 Spring Bean、参数化数据表、非确定性的运行时竞态(context.when().then() (8.9+))或 JSON 指令集无法提供的更丰富断言时,才使用 Java 备用方案。对于 CPT 8.8,由于不支持基于指令的格式,因此必须使用 Java 测试。请参阅 references/test-context.md;Web Modeler 无法识别 Java 测试。

5. 运行

从包含相关 pom.xml 的目录运行 Maven。对于 Node.js 布局,请使用生成的 test/ 目录,并确保此命令及每次重试都将 NODE_RESOURCE_DIR 设为解析后的资源目录,如 references/setup.md 中所述。

mvn test

如果失败,请参阅 references/troubleshooting.md 进行诊断。区分测试问题(变量拼写错误、元素 ID 错误、缺少指令)和流程问题(FEEL 条件错误、DMN 规则错误、错误代码错误)。修复对应的问题。重新运行。连续 3 轮修复均无进展后停止。

运行结束后,无论成功还是失败,都应立即继续执行第 6 步并打开覆盖率报告。

6. 覆盖率检查 — 退出门槛(100% 循环)

CPT 会在 target/coverage-report/report.html 生成覆盖率报告(按进程生成的 HTML;页面会在 window.COVERAGE_DATA JSON 字面量中嵌入完整的覆盖率数据集)。解析报告:

python3 - <<'PY'
import re, json
html = open("target/coverage-report/report.html").read()
# Balanced-brace extraction. Walk character by character, but track string
# state so braces inside JSON strings (e.g. inside a description) don't
# unbalance the counter.
m = re.search(r"window\.COVERAGE_DATA\s*=\s*", html)
start = html.index("{", m.end())
depth = 0; in_str = False; esc = False; end = start
for k, ch in enumerate(html[start:], start):
    if in_str:
        if esc: esc = False
        elif ch == "\\": esc = True
        elif ch == '"': in_str = False
    else:
        if ch == '"': in_str = True
        elif ch == "{": depth += 1
        elif ch == "}":
            depth -= 1
            if depth == 0:
                end = k + 1
                break
data = json.loads(html[start:end])
el = set(); flows = set(); total = None
for s in data["suites"]:
    for r in s["runs"]:
        for c in r["coverages"]:
            el.update(c.get("completedElements", []))
            flows.update(c.get("takenSequenceFlows", []))
            total = c.get("totalElementCount", total)
covered = len(el) + len(flows)
print(f"coverage={covered}/{total}={100*covered/total:.2f}%")
print("covered_elements:", sorted(el))
print("covered_flows:", sorted(flows))
PY

与 BPMN 元素及 sequenceFlow id 列表进行对比(grep -oE 'id="[A-Za-z0-9_]+"' <bpmn>,排除 _di、BPMNDiagram、BPMNPlane、Definitions_、ErrorDef_、TimerDef_、Signal_、Message_)。

mvn test 退出后,无论成功还是失败,都立即向用户显示 HTML 报告路径。 Agent 已通过上述 JSON 数据验证覆盖率;HTML 报告供用户检查。在最终回复中打印绝对路径(target/coverage-report/report.html),方便用户自行打开。在交互式本地会话中,你还可以主动提出代为打开(macOS 上使用 open,Linux 上使用 xdg-open,Windows 上使用 start)——在沙盒或远程环境中,不要未经用户提示就运行这些命令,因为它们不会产生任何效果。

预测遗漏时的修补循环——默认行为。 第 3 步中的集合覆盖规划应在首次编写时达到 100%。未达到时,差距就是预测遗漏:某个候选项的静态遍历与运行时行为不符。对每个未覆盖的 id:

  1. 对遗漏进行分类:元素(直接访问),或 sequence flow(必须命中其源节点,并且满足经由该流的条件路由——通常是规划器未能归因的网关分支)。
  2. 针对剩余未覆盖 id 重新运行贪心集合覆盖。将选出的候选项(通常只有一个)添加到场景文件中。
  3. 对于定时器边界事件:使用 INCREASE_TIME,并设置大于定时器周期的 ISO 8601 duration(例如,R/PT24H 对应 "PT25H")。边界事件会触发;下游路径的作业会创建;使用 COMPLETE_JOB 完成该作业。
  4. 对于消息边界事件:使用名称和 correlationKey 匹配的 PUBLISH_MESSAGE 指令。
  5. 重新运行第 5 步(mvn test)→ 第 6 步。每次迭代都应严格减少未覆盖集合;如果没有减少,说明规划器的路径预测有误——修复 references/coverage-strategy.md 中的预测逻辑,不要试图用更多场景掩盖问题。

会终止循环的硬性阻碍:

  • 连续 2 次迭代未覆盖的 id 集合相同——显示该列表并停止。
  • 未覆盖的元素是死代码(没有入向流,或其入向条件不可满足)——标记为 BPMN 缺陷,指出 camunda-bpmn,并停止。
  • 测试基础设施故障反复出现(Docker 未运行、部署解析错误)——停止并转到 references/troubleshooting.md。

只要仍有 id 未覆盖且不存在硬性阻碍,就不要宣布测试套件已完成。

注意:在早期的 8.9 SNAPSHOT 版本中,报告生成器可能会抛出 IllegalStateException: Report resources not found 并跳过 HTML 输出。测试仍会通过。遇到这种情况时,请从源文件出发,逐一对照 BPMN 与场景,以确认覆盖率。

7. 验证是否存在遗漏的冗余

第 3 步中的集合覆盖规划按设计应生成非冗余的测试套件。使用运行时覆盖率数据进行逐一排除检查:对每个场景,计算所有其他场景所覆盖 id 的并集;如果移除该场景后没有任何 id 丢失,则该场景是冗余的,说明规划器存在错误——修复规划器,然后删除该场景。

此外,请标记以下情况(检查成本低,无条件执行):

  • 场景名称不符合 <who/what> — <outcome> 格式(例如 "test1"、"happy")。
  • 多个场景的描述重复。
  • ASSERT_VARIABLE 指令检查的变量未被下游网关或 DMN 使用——数据断言不在范围内。
8. 报告

输出 Surefire 结果行、覆盖率百分比、分段数量,以及所有标记出的重复项。

Tests run: 6, Failures: 0, Errors: 0, Skipped: 0
Coverage: 100% (24/24 elements)
Segments: 1 happy path + 5 secondary
Duplicates flagged: 0

现有测试套件的维护工作流

如果测试已存在,而用户要求运行、诊断或改进测试(而不是生成全新的测试套件),请使用以下针对性工作流:

  1. 运行测试并诊断失败 — 在包含相关 pom.xml 的目录中执行 mvn test;对于 Node.js 项目布局,请在 test/ 目录中运行,并在首次运行及每次重试时设置 NODE_RESOURCE_DIR,使其指向已解析的资源目录。将每项失败归类为基础设施、测试或流程问题,然后分批修复。请参阅 references/troubleshooting.md 和 references/run-and-diagnose.md。
  2. 编写新测试前评估覆盖缺口 — 用业务术语说明当前测试套件的覆盖情况,列出尚未覆盖的分支、边界和规则,并推荐最少的一组后续场景。请参阅 references/evaluation.md。
  3. 将测试接入 CI — 配置 CI 以可靠地运行 CPT 并发布 JUnit 测试产物;可选择仅在受信任分支上运行集成配置文件。请参阅 references/ci.md。

这些工作流相辅相成:先评估覆盖缺口,再实现新场景,然后在本地和 CI 中运行并诊断测试。

参考资料

  • setup.md — Java、Maven、Docker 的先决条件;CPT 依赖项;测试脚手架布局;Spring Boot 4.x 固定版本
  • coverage-strategy.md — 各 BPMN 元素类型的场景选择规则,包括临时子流程工具的激活
  • authoring.md — .test.json 架构、完整的 8.9 指令参考、Java 备用方案
  • test-context.md — CamundaProcessTestContext Java API 接口(作业/决策/子流程模拟、时间控制、条件行为)
  • connectors-runtime.md — 在 Zeebe 旁启用 Connectors 运行时;WireMock 模式;入站 Webhook
  • troubleshooting.md — 失败诊断表(测试问题与流程问题)
  • run-and-diagnose.md — 测试运行循环和分批修复失败的策略
  • evaluation.md — 覆盖缺口评估与建议工作流
  • ci.md — 用于执行 CPT 和发布测试报告的 CI 流水线模式

评论

支持 Markdown