java-tests-tzatziki について
Tzatziki の定義済みステップパターンを使い、機能仕様から Cucumber の `.feature` テストを作成するスキルです。Java プロジェクトの調査、計画の承認、作成前の検証を案内します。
主な機能
- 01文書化された Tzatziki ステップの使用
- 02プロジェクトのモジュールと資料の確認
- 03Cucumber テストのブートストラップ確認
- 04承認用シナリオ計画の提示
- 05既存テストの実行検証
活用シーン
- 01機能仕様からテストを作成
- 02追加アサーションに合わせて既存シナリオを拡張
- 03任意のエラーケースや境界条件を特定
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ decathlon/ tzatziki --skill java-tests-tzatzikiインストール後、Claude Code で/java-tests-tzatzikiを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/bootstrap-templates.mdcli-execution.mdsteps-core.mdsteps-http.mdsteps-jackson3.mdsteps-kafka.mdsteps-logback.mdsteps-mcp.mdsteps-opensearch.mdsteps-spring-jpa.mdsteps-spring-kafka.mdsteps-spring-mongodb.mdsteps-spring.md詳細
Tzatziki による BDD テストの生成
Tzatziki のステップ定義ライブラリを有効なステップパターンの情報源として使用し、ユーザーの機能仕様から有効な Cucumber .feature ファイルを生成します。
原則
これらはワークフローの背後にある考え方を説明するものです。理解しておくと、ワークフローで明示的に扱われていないケースにも対応しやすくなります。
-
ステップは想像ではなく、コードから導きます。 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 ソースを読み直してください。 -
テストを書く前に環境を検証します。 新しい feature ファイルを作成する前に、対象モジュールの既存の Cucumber テストを少なくとも 1 つ実行してください。これにより、依存関係の不足、ブートストラップの不具合、ランナーの設定ミスを早期に検出でき、実行できないシナリオを書くことに時間をかけずに済みます。テストがまだない場合は、まず最小限のブートストラップを作成し、少なくとも 1 つのシナリオが検出されることを確認してください。
-
構造化データには、原則として YAML を使います。 リクエストボディ、データベースのフィクスチャ、Kafka のペイロード、期待される結果は、
"""ymlのドキュメント文字列を使うと、Tzatziki のシナリオが最も読みやすくなります。表形式が自然なデータには Gherkin テーブルを使い、JSON 契約で必要な場合に限って生の JSON を使ってください。 -
ユーザーが依頼した範囲を正確にカバーし、そのうえで見落としがないか考える手助けをします。 ユーザーの仕様にある機能動作を、正常系だけでなくすべてシナリオにしてください。ただし、追加のシナリオを黙って加えてはいけません。依頼された範囲をカバーした後、エッジケースを積極的に特定し、任意の追加項目としてユーザーに提示してください。エッジケースを効果的に特定するには、次の 3 点を確認します。(a)シナリオ内のすべての外部サービス呼び出しについて、エラー(4xx、5xx)が返された場合やタイムアウトした場合はどうなるか。(b)すべてのデータコレクションについて、空の場合や想定外の値を含む場合はどうなるか。(c)プロジェクト内にある、類似機能をテストする既存のテストファイル。そこには、新しいシナリオに応用できるエラー処理パターンが含まれていることがよくあります。どのエッジケースを含めるかはユーザーが決めますが、重要なことを見落とさないよう、候補を提示するのがあなたの役割です。
-
既存のものを再利用します。 プロジェクトにランナー、ブートストラップクラス、feature の配置規約、glue の設定がすでにある場合は、それらを再利用してください。重複して作成すると、クラスパスの競合を招き、テストの検出を混乱させます。
-
新しいシナリオを作るより、既存のシナリオを更新することを優先します。 仕様によって、すでにテスト済みの動作(たとえば「このフローがすでに公開しているメッセージに
traceIdヘッダーを追加する」)に新しいフィールド、ヘッダー、アサーションが追加される場合、ほとんどの場合、新しいシナリオを作成して同じ Given/When のセットアップを重複させるのではなく、その動作をすでに検証している既存シナリオのThenアサーションを変更するのが適切です。新しいシナリオの作成が妥当なのは、その動作自体が本当に新しい場合に限られます。つまり、既存のシナリオがカバーしていない別のトリガー、別のコードパス、または異なる事前条件の組み合わせがある場合です。テストスイートはすぐに大きくなり、シナリオが重複するたびに保守の負担が増えるため、この点は重要です。共有セットアップが変わったとき、スイートの一貫性を保つには、重複したすべてのコピーを同時に更新する必要があります。
ワークフロー
1. 仕様を理解する
ユーザーの入力を分析し、個別の機能動作をチェックリストにまとめます。それぞれの動作から、1つ以上のシナリオを作成します。曖昧な点があれば、先に質問してください。
分析の際、各動作を次のいずれかに分類します。
- 新しい動作 — 既存のシナリオではカバーされていない、新たなトリガー、コードパス、または前提条件の組み合わせです。新しいシナリオが必要です。
- 追加的な変更 — すでにテスト済みの動作に、新しいフィールド、ヘッダー、アサーション、または出力を追加します(例:「このシナリオがすでに送信しているメッセージに
traceIdヘッダーを追加する」)。新しいシナリオを作成するのではなく、既存のシナリオのアサーションを変更して対応します。原則 6 を参照してください。
また、次の項目も抽出します。
- 外部依存関係 — 機能が連携するすべての API、サービス、データソースです。それぞれが、エッジケースのシナリオ(エラー、タイムアウト、空のレスポンスなど)の候補になります。
- パフォーマンスまたは信頼性に関するヒント — 仕様にパフォーマンス上の懸念、大量のデータ、またはエラー処理への言及があれば、記録します。ユーザーが明示的な受け入れテストを書いていなくても、重視している可能性のあるシナリオを示しています。
- 暗黙的なエラーパス — 仕様に「サービス X を呼び出して Y を取得する」とある場合、成功パスが記述されています。失敗パス(サービス X がエラーを返す場合)は、提案すべきエッジケースです。
2. プロジェクトを調べる
ビルドツールを検出し(ラッパーを優先します。mvn より ./mvnw、gradle より ./gradlew)、次の手順を実行します。
- 必ず
references/steps-core.mdを読みます — すべての Tzatziki プロジェクトで、変数、アサーション、データ操作にコアステップ定義(ObjectSteps)が使われています。 pom.xmlまたはbuild.gradleの依存関係宣言を調べ、プロジェクトが依存するtzatziki-*モジュールを検出します。簡単に抽出する方法は次のとおりです。grep -o 'tzatziki-[a-z-]*' pom.xml | sort -u- 検出した依存関係に基づき、該当するモジュール別リファレンスを読みます。
- 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
- HTTP/REST テスト →
.featureの例から推測したステップのパターンと、Java の*Steps.javaソースから読み取ったパターンに迷った場合は、Java ソースを優先します。- 調査中に見つけた既存の
.featureファイルから、エラー処理のパターンを整理します。HTTP エラーレスポンス(例:外部 API からの 404/500 のモック)、空データ、キャッシュミス、リトライの動作をプロジェクトがどのようにテストしているかを確認します。ステップ 5 でエッジケースを提案する際に、これらのパターンをテンプレートとして使用します。
3. ブートストラップを確認する
既存のテスト基盤を検索します。
- ランナー:
@Suite+@IncludeEngines("cucumber")(JUnit 5)またはAbstractTestNGCucumberTests - フィーチャーの場所:
@SelectClasspathResource(...)または@SelectDirectories(...) - Spring コンテキスト:
@CucumberContextConfiguration+@SpringBootTest(Spring を使用している場合)
不足しているものがあれば、作成する計画を立てます。JUnit 5 ランナーと Spring 設定のテンプレートについては、references/bootstrap-templates.md を読みます。
4. 環境を検証する
対象モジュールで既存のテストスイートを実行し、正常に動作することを確認します。
# Maven
./mvnw -pl <module> -Dtest=<RunnerClass> test
# Gradle
./gradlew :<module>:test --tests <RunnerClass>
テストが成功する場合も、機能上の失敗がある場合も問題ありません。重要なのは、Cucumber がシナリオを検出して実行することです。Tests run: 0 と表示される場合は、ランナーまたはフィーチャーの検出に問題があり、新しいものを書く前に修正する必要があります。
5. 計画を提案する
⛔ これは必須のチェックポイントです。 ユーザーの明示的な承認を得るまで、ステップ 6 に進んではいけません。ユーザーの仕様に詳細な受け入れテストがすでに含まれている場合でも、必ず計画を提示してください。ユーザーは計画を確認し、範囲を調整したい場合があり、気になるエッジケースを追加または承認する機会を必要としています。このステップを省略すると、誤ったテストを生成し、労力を無駄にするおそれがあります。
まず、計画の全容を通常の回答テキストとして出力してください(長い計画を ask_user の質問に埋め込んではいけません。UI で切り捨てられます)。以下を含めてください。
- 作成または変更するファイル
- リクエストされた各機能の動作とシナリオを対応付ける表 — 各行に、そのシナリオが既存シナリオの変更か、新規シナリオかを示します。判断にはステップ 1 の動作の分類を使用してください。
- 必要なブートストラップ作業
- 提案するエッジケース(任意であることを明記)— その特定方法については以下を参照してください。
既存シナリオの変更を優先する
新しいシナリオを提案する前に、プロジェクト内の既存の .feature ファイルを検索し、同じ動作フロー(同じエンドポイント、Kafka トピック、トリガー)をすでにテストしているシナリオがないか確認してください。該当するシナリオが見つかった場合、既定ではそのシナリオを変更してください。たとえば、既存の Then アサーションテーブルに新しいフィールドを追加したり、ヘッダーチェックを追加したりします。Given/When ステップが重複するシナリオを作成するのは避けてください。これにより、テストの肥大化と保守の負担を抑えられます。
新しいシナリオを作成するのは、次の場合に限ります。
- 関連する動作フローをカバーする既存シナリオがない
- 新しい動作に本質的に異なる前提条件(異なるデータ設定、異なるトリガー、異なるエラーパス)が必要で、既存シナリオに組み合わせると分かりにくくなる
- ユーザーがシナリオを分けるよう明示的に依頼している
例 — 既存の送信メッセージに traceId ヘッダーを追加する場合:
- ❌ 誤り:既存のメッセージ送信シナリオの
Given/When全体をコピーし、headers: traceId: abc-123を追加するだけの「published message includes traceId header」という新しいシナリオを作成する - ✅ 正しい:既存のメッセージ送信シナリオの
Thenブロックを変更し、既存のアサーションに加えてheaders: traceId: abc-123を含める
その後、ask_user ツールを使い、ユーザーの判断だけを尋ねる短く焦点を絞った質問をしてください(例:「この計画でよろしいですか。また、任意のエッジケースのうち、どれを含めますか?」)。ユーザーが確認するまで、.feature ファイルを書いてはいけません。
エッジケースの特定
ステップ 1 と 2 で把握した外部依存関係、エラーパターン、仕様上のヒントを使って、任意のエッジケースシナリオの具体的なリストを作成してください。次のカテゴリを確認します。
-
外部サービスの障害 — シナリオ内の各外部 API 呼び出しについて、以下の場合にどうなるかを検討します。
- クライアントエラー(400、404)が返る場合 — 例:リソースが存在しない
- サーバーエラー(500、502、503)が返る場合 — 例:サービスが停止している
- レスポンスボディが空、または想定外の場合
-
空のデータと境界値 — 関連する各データコレクションについて、以下を検討します。
- コレクションが空の場合はどうなるか(例:モデルがないスーパーモデル、記事がないモデル、
valueリストが空のオーバーライドルール) - 要素が 1 つの場合と複数ある場合
- 値が null または欠落している場合
- コレクションが空の場合はどうなるか(例:モデルがないスーパーモデル、記事がないモデル、
-
状態と順序 — キャッシュヒットとキャッシュミス、既存データと新規データ、同時変更、失敗後の再試行(CREATED → TO_RETRY → ERROR)。
-
既存テストのパターン — ステップ 2 で、プロジェクト内の既存の
.featureファイルにあるエラー処理パターンをまとめています。それらのパターンを新機能に適用してください。たとえば、既存のテストで/masterdata/v2/arbo/models/{id}/articlesに対する 404 をモックし、「0 kafka messages」をアサートしている場合は、新機能が呼び出す外部 API にも同じパターンを提案します。
提案する各エッジケースには、1 行の説明を付け、**(任意)**と明記してください。どれを含めるかはユーザーが決定します。
6. 実装と検証
⛔ 必須:応答する前にテストを実行してください。
.featureファイルを作成または変更した後は、テストを必ず実行し、応答する前に出力に"step(s) are undefined"またはUndefinedStepExceptionのエラーが一切ないことを確認してください。この検証が完了するまで、概要表を提示したり、「実装が完了しました」と宣言したり、フィードバックを求めたりしないでください。ステップテキストを目視で確認するだけでは不十分です。テストランナーの出力だけが信頼できる情報です。
- ステップ 2 の正確なステップパターンを使い、既存プロジェクトのスタイル(シナリオの命名、
Backgroundの使用、タグ、データ形式の規則)に合わせて.featureファイルを記述します。 - フィーチャーの規約がない場合は、
src/test/resources/featuresと@SelectClasspathResource("features")を既定として使用します。 - テストを実行し、出力を確認します。 ステップの有効性を判断する基準はテスト出力です。目視確認では代替できません。特に以下のエラーを確認してください。
"step(s) are undefined"+"You can implement these steps"— ステップテキストが登録済みのステップ定義と一致していないことを意味します。これは最もよくある間違いであり、タスクを完了と見なす前に必ず修正してください。モジュールごとのreferences/steps-*.mdファイルに戻り、正しいパターンを見つけてステップを書き直してください。UndefinedStepException— 同じ根本原因ですが、表示形式が異なります。ParseError— Gherkin の構文が正しくありません。Tests run: 0— ランナーまたはフィーチャーの検出に問題があります。 機能上のアサーション失敗(例:expected 200 but got 404)は許容されます。プロダクトの動作がまだ実装されていない場合、BDD では想定されることです。
- ステップ 1 で要求されたすべての動作が含まれ、テスト出力に未定義ステップのエラーが一切残らなくなるまで繰り返します。
実装後の変更
ユーザーがすでに記述したシナリオの変更(例:Scenario Outline への変換、アサーションの追加、ステップの統合、名前の変更、構成の変更など)を求めた場合も、検証要件は適用されます。
.featureファイルに要求された編集を適用します。- すぐにテストを再実行してください。 変更が些細に見える場合も同様です。ステップテキストの構成変更、新しい
Thenアサーションの追加、表の再編成では、テストランナーでしか検出できない微妙な構文の不一致が頻繁に発生します。 - 未定義ステップのエラーが発生した場合は、ユーザーに応答する前に修正してください。
このループ(編集 → 実行 → 修正)は、初回の実装だけでなく、すべての変更に適用されます。ユーザーが「小さな」変更を求めている場合でも、テストの実行を省略しないでください。
CLI から特定のフィーチャーを実行する場合: 特定のフィーチャーファイルまたはシナリオ行を指定する必要がある場合は、セレクターとして cucumber.features を使用してください。-Dtest=... や cucumber.filter.name は使用しないでください。cucumber.features を使うと、ランナーの @ConfigurationParameter アノテーションを迂回するスタンドアロンの Cucumber 実行が起動されるため、詳細については references/cli-execution.md を参照してください。
成功条件
- 新しいシナリオを作成する前に、既存のテストを少なくとも1つ実行し、正常に動作することを確認していること。
.featureファイルを作成する前に、計画をユーザーに提示し、承認を得ていること。- 生成されたシナリオが、ユーザーから明示的に要求された機能動作を100%網羅していること。
- すべてのステップテキストが実際の Tzatziki ステップ定義に由来していること(ステップを創作しないこと)。特に、ステップの正規表現が特定のキーワードまたは空文字列を要求する場合、自然言語の類義語に置き換えていないこと(原則1を参照)。
- すべての
.featureファイルの編集後(初回実装とその後の変更の両方)にテストを実行し、出力に「undefined step」エラーが1つもないこと。 これが決定的な検証です。テスト出力に"step(s) are undefined"と表示された場合、タスクは完了していません。同じターン内でテストを実行する前に、エージェントが実装完了を宣言したり、概要を提示したりしてはいけません。 - 必要なテストランナーまたは 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:Spring を使用しない 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を使って CLI から単一の feature またはシナリオを実行する方法。Maven/Gradle のプロパティミラーリングの仕組みも含みます。テストスイート全体ではなく、特定の.featureファイルを対象にする必要がある場合にお読みください。