mcpField
J
java-tests-tzatziki

java-tests-tzatziki

github.com/decathlon其他8829 次安装6 天前更新
代码仓库

关于 java-tests-tzatziki

根据功能规格,使用 Tzatziki 已定义的步骤模式生成 Cucumber `.feature` 测试的技能,指导 Java 项目检查、方案审批及测试创建前的验证。

主要功能

  1. 01使用文档中的 Tzatziki 步骤模式
  2. 02检查项目模块及参考资料
  3. 03检查 Cucumber 测试引导配置
  4. 04提出场景方案并等待审批
  5. 05验证现有测试能否运行

适用场景

  1. 01根据功能规格编写测试
  2. 02为新增断言扩展现有场景
  3. 03识别可选的错误及边界情况

安装

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

$npx skills add https://github.com/decathlon/tzatziki --skill java-tests-tzatziki

安装后在 Claude Code 中输入/java-tests-tzatziki确认已加载。

包含的文件

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

references/
bootstrap-templates.md
cli-execution.md
steps-core.md
steps-http.md
steps-jackson3.md
steps-kafka.md
steps-logback.md
steps-mcp.md
steps-opensearch.md
steps-spring-jpa.md
steps-spring-kafka.md
steps-spring-mongodb.md
steps-spring.md

详细介绍

使用 Tzatziki 生成 BDD 测试

根据用户的功能规范生成有效的 Cucumber .feature 文件,并以 Tzatziki 的步骤定义库作为合法步骤模式的权威来源。

原则

这些原则阐明了工作流背后的考量,理解它们有助于处理工作流未明确涵盖的边缘情况。

  1. 步骤来自代码,而非凭空想象。 Tzatziki 在其 *Steps.java 文件中提供了数百种预置的 @Given / @When / @Then 模式。编造与实际定义不匹配的步骤文本会在运行时产生 UndefinedStepException。每个模块的参考文件 references/steps-*.md 包含所有合法的步骤模式;编写任何场景之前,请先阅读相关文件。

    ⚠️ 绝不要改述或临时编造步骤关键词。 许多步骤模式使用 COMPARING_WITH 等正则表达式常量,它们会展开为一小组固定关键词(例如,"" 表示空字符串、" exactly"、" at least"、" only")。不要替换成“containing”“including”“matching”或任何其他“听起来合适”的自然语言同义词——如果该词未出现在 @Given / @When / @Then 注解的正则表达式中,运行时就会将该步骤视为未定义。如有疑问,请重新阅读 references/steps-*.md 中的 Java 源码,而不要猜测。

  2. 编写测试前先验证环境。 创建新的功能文件前,至少在目标模块中运行一个现有的 Cucumber 测试。这样可以尽早发现缺少依赖、引导流程损坏或运行器配置错误,避免先花精力编写无法执行的场景。如果还没有任何测试,请先创建最精简的引导配置,并确认它至少能发现一个场景。

  3. 结构化数据默认使用 YAML。 当请求正文、数据库固件、Kafka 负载和预期结果使用 """yml 文档字符串时,Tzatziki 场景最易于阅读。对于天然适合表格的数据,可改用 Gherkin 表格;只有契约要求时才使用原始 JSON。

  4. 准确覆盖用户要求的内容,然后帮助他们考虑遗漏之处。 为用户规范中的每项功能行为生成场景,而不只是覆盖正常路径。但也不要擅自添加额外场景。应先覆盖用户要求的范围,然后主动找出边缘情况,并将其作为可选补充项呈现给用户。要有效识别边缘情况,请关注三方面:(a) 场景中的每次外部服务调用——如果返回错误(4xx、5xx)或超时,会发生什么?(b) 每个数据集合——如果为空或包含意外值,会发生什么?(c) 项目中测试类似功能的现有测试文件——其中通常包含可改用于新场景的错误处理模式。由用户决定是否纳入这些边缘情况,但你的职责是主动指出它们,避免遗漏重要内容。

  5. 复用现有内容。 如果项目已有运行器、引导类、功能文件位置约定或 glue 配置,就复用它们。创建重复项会导致类路径冲突,也会让测试发现变得混乱。

  6. 优先更新现有场景,而不是创建新场景。 当规范为已测试的行为添加新字段、标头或断言时(例如,“为此流程已发布的消息添加一个 traceId 标头”),通常应当修改现有场景的 Then 断言;该场景已经覆盖此行为,而不是创建一个全新的场景,仅为检查一个附加字段就重复所有相同的 Given / When 设置。只有当行为本身确实是新的——例如触发条件不同、代码路径不同,或现有场景都未覆盖的前置条件组合——才有理由创建新场景。这一点很重要,因为测试套件会迅速增长,每个重复场景都会增加维护负担:共享设置发生变化时,必须同步更新每个副本,否则测试套件就会变得不一致。

工作流

1. 理解规格说明

分析用户的输入,并将其拆分为不同功能行为的检查清单。每种行为都将对应一个或多个场景。如果有任何不明确之处,请先询问。

分析时,将每种行为归类为以下一种:

  • 新行为 — 真正新增的触发条件、代码路径或前置条件组合,现有场景均未覆盖。这需要新增场景。
  • 增量变更 — 在已测试行为中新增字段、标头、断言或输出(例如,“为此场景已发布的消息添加 traceId 标头”)。这应通过修改现有场景的断言来处理,而不是创建新场景。参见原则 6。

还要提取:

  • 外部依赖 — 此功能涉及的每个 API、服务或数据源。每一项都可能带来边缘场景(错误、超时、空响应)。
  • 性能或可靠性提示 — 如果规格说明提到性能问题、大量数据或错误处理,请记录下来。这些提示意味着用户可能会关注相关场景,即使他们没有明确编写验收测试。
  • 隐含错误路径 — 如果规格说明说“调用服务 X 获取 Y”,描述的就是成功路径。失败路径(服务 X 返回错误)是建议补充的边缘情况。
2. 探索项目

检测构建工具(优先使用包装器:./mvnw 优于 mvn,./gradlew 优于 gradle),然后:

  1. 始终阅读 references/steps-core.md — 核心步骤定义(ObjectSteps)用于每个 Tzatziki 项目的变量、断言和数据处理。
  2. 通过检查 pom.xml 或 build.gradle 中的依赖声明,检测项目依赖了哪些 tzatziki-* 模块。快速提取方式:
    grep -o 'tzatziki-[a-z-]*' pom.xml | sort -u
    
  3. 根据检测到的依赖,阅读相应的模块参考资料:
    • HTTP/REST 测试 → references/steps-http.md
    • Spring 上下文 → references/steps-spring.md
    • JPA/数据库 → references/steps-spring-jpa.md
    • Kafka 消息传递(原生 Apache Kafka)→ references/steps-kafka.md
    • Kafka 消息传递(Spring Kafka)→ references/steps-spring-kafka.md
    • MongoDB → references/steps-spring-mongodb.md
    • OpenSearch → references/steps-opensearch.md
    • 日志断言 → references/steps-logback.md
    • MCP/AI 测试 → references/steps-mcp.md
  4. 如果从 .feature 示例推断出的步骤模式与从 Java *Steps.java 源码中读到的模式不一致,请以 Java 源码为准。
  5. **整理发现过程中遇到的现有 .feature 文件中的错误处理模式。**记录项目如何测试 HTTP 错误响应(例如,模拟外部 API 返回 404/500)、空数据、缓存未命中或重试行为。第 5 步中建议边缘情况时,请将这些模式用作模板。
3. 检查引导配置

搜索现有测试基础设施:

  • 运行器:@Suite + @IncludeEngines("cucumber")(JUnit 5)或 AbstractTestNGCucumberTests
  • 功能文件位置:@SelectClasspathResource(...) 或 @SelectDirectories(...)
  • Spring 上下文:@CucumberContextConfiguration + @SpringBootTest(如果使用 Spring)

如果缺少任何部分,请计划创建。阅读 references/bootstrap-templates.md,了解 JUnit 5 运行器和 Spring 配置模板。

4. 验证环境

在目标模块中运行现有测试套件,确认其可以正常工作:

# Maven
./mvnw -pl <module> -Dtest=<RunnerClass> test
# Gradle
./gradlew :<module>:test --tests <RunnerClass>

测试通过或因功能问题而失败都可以——关键是 Cucumber 能发现并执行场景。Tests run: 0 表示运行器或功能文件发现配置存在问题,必须先修复再编写新内容。

5. 提出计划

⛔ 这是一个强制检查点。 未经用户明确批准,不得继续执行步骤 6。即使用户的规格说明已包含详细的验收测试,也要照常提交计划——用户希望审阅计划,可能想调整范围,也需要有机会批准计划或补充他们关心的边界情况。跳过此步骤可能导致生成错误的测试并浪费精力。

先将完整计划作为普通回复文本输出(切勿将冗长计划嵌入 ask_user 问题中——界面会截断内容)。请包含:

  • 要创建或修改的文件
  • 将每项请求的功能行为映射到相应场景的表格——每一行都要标明该场景是修改(更新现有场景)还是新增。根据步骤 1 的行为分类作出判断。
  • 所需的任何引导工作
  • 建议的边界情况(明确标记为可选)——关于如何识别这些情况,请参阅下文
优先修改现有场景

在提出新场景之前,先搜索项目现有的 .feature 文件,查找已覆盖相同行为流程(相同端点、相同 Kafka 主题、相同触发条件)的场景。找到后,默认应修改该场景——例如,在其 Then 断言表中新增一个字段,或添加一项标头检查——而不是创建一个内容重复的新场景。这样可以避免测试臃肿和维护开销。

仅在以下情况创建新场景:

  • 现有场景完全没有覆盖相关行为流程
  • 新行为需要截然不同的前置条件(不同的数据设置、不同的触发条件、不同的错误路径),若与现有场景合并会令人困惑
  • 用户明确要求单独创建场景

示例——为现有发送的消息添加 traceId 标头:

  • ❌ 错误:创建一个“published message includes traceId header”新场景,复制现有消息发布场景的全部 Given/When 步骤,只为添加 headers: traceId: abc-123
  • ✅ 正确:修改现有消息发布场景的 Then 块,在已有断言中加入 headers: traceId: abc-123

然后使用 ask_user 工具提出一个简短、聚焦的问题,只询问用户的决定(例如:“这个计划是否合适?你希望纳入哪些可选边界情况?”)。在用户确认之前,不要编写任何 .feature 文件。

识别边界情况

利用你在步骤 1 和步骤 2 中收集的外部依赖、错误模式和规格提示,整理一份具体的可选边界场景列表。逐一考虑以下类别:

  1. 外部服务故障——针对场景中的每个外部 API 调用,考虑其返回以下内容时会发生什么:

    • 客户端错误(400、404)——例如,资源不存在
    • 服务端错误(500、502、503)——例如,服务不可用
    • 空响应正文或内容异常的响应正文
  2. 空数据和边界数据——针对涉及的每个数据集合:

    • 如果集合为空会怎样?(例如,没有模型的超级模型、没有文章的模型、value 列表为空的覆盖规则)
    • 集合只包含一个元素与包含多个元素时有何不同?
    • 值为 null 或缺失时会怎样?
  3. 状态和顺序——缓存命中与未命中、已有数据与新数据、并发修改、失败后重试(CREATED → TO_RETRY → ERROR)。

  4. 现有测试中的模式——在步骤 2 中,你已整理项目现有 .feature 文件中的错误处理模式。将这些模式应用到新功能中。例如,如果现有测试会模拟 /masterdata/v2/arbo/models/{id}/articles 返回 404,并断言“0 条 kafka 消息”,那么对于新功能调用的任何外部 API,也建议采用相同模式。

每条建议的边界情况都应以一句话描述,并标记为**(可选)**。由用户决定是否纳入。

6. 实施与验证

⛔ 必须:回复前运行测试。 编写或修改任何 .feature 文件后, 必须运行测试,并确认输出中没有 "step(s) are undefined" / UndefinedStepException 错误,然后才能回复用户。在验证通过之前,不要提供摘要 表、宣称“实施完成”或征求反馈。 仅凭目视检查步骤文本并不足够——只有测试运行器的输出才是权威依据。

  1. 使用步骤 2 中的精确步骤模式编写 .feature 文件,并遵循现有项目的风格(场景命名、Background 的使用方式、标签、数据格式约定)。
  2. 如果没有现成的功能文件约定,则默认使用 src/test/resources/features,并使用 @SelectClasspathResource("features")。
  3. 运行测试并检查输出。 测试输出是判断步骤是否有效的依据——目视检查再仔细也不能替代它。重点检查以下错误:
    • "step(s) are undefined" + "You can implement these steps" — 表示步骤文本与任何已注册的步骤定义都不匹配。这是最常见的错误,任务完成前必须修复。返回对应模块的 references/steps-*.md 文件,找到正确的模式并重写步骤。
    • UndefinedStepException — 根本原因相同,只是呈现方式不同。
    • ParseError — Gherkin 语法格式错误。
    • Tests run: 0 — 测试运行器或功能文件发现机制存在问题。 可以接受功能断言失败(例如 expected 200 but got 404)——当产品行为尚未实现时,这类失败在 BDD 中是预期的。
  4. 重复此过程,直到步骤 1 中要求的所有行为都已涵盖,并且测试输出中不再有未定义步骤错误。
实施后的修改

当用户要求更改已编写的场景时(例如转换为 Scenario Outline、添加断言、合并步骤、重命名或重组),仍须遵循验证要求:

  1. 对 .feature 文件应用所请求的修改。
  2. 立即重新运行测试——即使修改看起来微不足道。重组步骤文本、添加新的 Then 断言或调整表格结构,都经常会引入只有测试运行器才能发现的细微语法不匹配。
  3. 如果出现未定义步骤错误,必须先修复,再回复用户。

此循环(编辑 → 运行 → 修复)适用于每一次修改,而不仅是初次实施。即使用户只要求做“一个小改动”,也绝不可跳过测试运行。

从 CLI 运行单个功能文件: 需要指定某个功能文件或场景行时,请使用 cucumber.features 作为选择器,而不是 -Dtest=... 或 cucumber.filter.name。详情请阅读 references/cli-execution.md,因为 cucumber.features 会触发独立的 Cucumber 执行,绕过运行器的 @ConfigurationParameter 注解。

成功标准

  • 编写新场景之前,至少运行并确认一个现有测试正常运行。
  • 编写任何 .feature 文件之前,先向用户展示计划并获得批准。
  • 生成的场景覆盖用户明确要求的 100% 功能行为。
  • 所有步骤文本均来自真实的 Tzatziki 步骤定义(不得编造步骤)。尤其是,步骤正则表达式要求特定关键词或空字符串时,不得用自然语言同义词替代(参见原则 1)。
  • 每次编辑 .feature 文件后(包括初始实现和后续修改)都要运行测试,且输出中不得出现任何“undefined step”错误。 这是最终验证标准——如果测试输出显示 "step(s) are undefined",任务就尚未完成。Agent 必须在同一轮中先运行测试,然后才能宣布实现完成或提供总结。
  • 所需的运行器或 Spring 引导文件均已就位。
  • 使用正确的构建工具命令发现并执行测试。
  • 识别边缘情况,将其展示给用户,并且只有在获得批准后才纳入。
  • 任何剩余失败都应是功能断言失败,而非技术设置问题。

参考文件

需要时阅读这些文件——其中包含模板和详细指南,若放在主工作流中会显得冗长:

各模块步骤参考(根据检测到的依赖项阅读)
  • references/steps-core.md — ObjectSteps:变量、断言、数据处理、类型转换。务必阅读此文件——每个 Tzatziki 项目都会用到核心步骤。
  • references/steps-http.md — HttpSteps:HTTP 模拟、请求/响应断言、REST API 测试。项目使用 tzatziki-http 时阅读。
  • references/steps-spring.md — SpringSteps:Spring 上下文、属性、Bean 操作。项目使用 tzatziki-spring 时阅读。
  • references/steps-spring-jpa.md — SpringJPASteps:JPA 实体管理、数据库测试数据、持久化断言。项目使用 tzatziki-spring-jpa 时阅读。
  • references/steps-kafka.md — KafkaSteps:纯 Apache Kafka 主题管理、消息生成/消费、异步断言。项目使用 tzatziki-kafka(不依赖 Spring)时阅读。
  • references/steps-spring-kafka.md — SpringKafkaSteps:Spring 专用 Kafka 扩展(等待监听器消费、拦截器控制、嵌入式代理)。基于核心 tzatziki-kafka 步骤。项目使用 tzatziki-spring-kafka 时阅读。
  • references/steps-spring-mongodb.md — SpringMongoSteps:MongoDB 集合管理、文档测试数据、查询断言。项目使用 tzatziki-spring-mongodb 时阅读。
  • references/steps-opensearch.md — OpenSearchSteps:索引管理、文档索引、搜索断言。项目使用 tzatziki-opensearch 时阅读。
  • references/steps-logback.md — LoggerSteps:日志断言、日志级别管理。项目使用 tzatziki-logback 时阅读。
  • references/steps-mcp.md — McpSteps:MCP 服务测试、工具调用、AI 集成。项目使用 tzatziki-test-mcp 时阅读。
  • references/steps-jackson3.md — Jackson 3 映射器实现、序列化行为和委托选择。项目使用 tzatziki-jackson3 时阅读。
其他参考
  • references/bootstrap-templates.md — JUnit 5 运行器和 Spring @CucumberContextConfiguration 模板。需要创建新的运行器或 Spring 引导类时阅读。
  • references/cli-execution.md — 如何通过命令行使用 cucumber.features 运行单个功能文件或场景,包括 Maven/Gradle 属性镜像机制。需要指定某个 .feature 文件,而非运行完整测试套件时阅读。

评论

支持 Markdown