Gherkinは、BDD(振る舞い駆動開発)で仕様を書く言語で、人が読める平文のまま自動テストとして実行できる点に特徴があります。ただ「前提・もし・ならば」の3語を覚えても、実際に .feature を書き始めると手が止まります。Ruleはどこに置くのか、Backgroundは1ファイルに何個まで置けるのか、日本語で書くには何を宣言すればよいのか。この記事はCucumber公式のGherkinリファレンスと、パーサ本体が持つ言語定義ファイル gherkin-languages.json を一次情報に、キーワードの全体像・動く .feature のコード・日本語ロケール・フレームワークの対応差をまとめたものです。
まとめ:Gherkinの正本は gherkin-languages.json で、Rule対応はフレームワークごとに違う
- Gherkinのキーワードは
gherkin-languages.jsonで言語ごとに定義され、英語では Feature・Rule・Background・Scenario・Scenario Outline・Examples とステップ系5種の計11種が登録されています。 - 1つの .feature ファイルに書ける Feature は1つだけで、Background も Feature または Rule ごとに1組だけです。
- Given・When・Then はステップ定義の照合に使われず、文言が同じステップはキーワードが違っても重複として扱われます。
- 先頭行に
# language: jaを書けば「機能」「背景」「前提」「もし」「ならば」で記述でき、言語定義は80言語ぶん同梱されています。 - Rule はGherkin v6で追加されたキーワードで、対応時期はフレームワークごとに違います(pytest-bddは8.0.0、behaveは1.3.0以降)。
- .NET系はSpecFlowが2024年12月31日にEOLを迎えたため、新規はReqnroll一択です。
以下、キーワードと実際の記述、日本語ロケール、フレームワークの差、見送るべき状況の順に整理します。
Gherkinの全キーワードと.featureファイルの基本構造
Gherkinの語彙は、パーサのリポジトリにある gherkin-languages.json という1つのJSONファイルが正本です。ここに登録されていない語はキーワードとして解釈されません。用途を仕様記述に限定した外部DSLであり、条件分岐やループといった制御構文は言語として持ちません。英語(en)の定義は次の11種で、これに全ステップ共通の別名としてアスタリスクが加わります。
| キーワード | 分類 | 日本語(ja) | 役割 |
|---|---|---|---|
| Feature | 宣言 | 機能/フィーチャ | ファイルの主題。1ファイル1つ |
| Rule | 宣言 | ルール | 業務ルール単位のシナリオ群 |
| Example/Scenario | 宣言 | シナリオ | 具体例1件 |
| Background | 宣言 | 背景 | 各シナリオ前の共通Given |
| Scenario Outline | 宣言 | シナリオアウトライン | 値を差し替える雛形 |
| Examples/Scenarios | 宣言 | 例/サンプル | Outlineに流し込む値の表 |
| Given | ステップ | 前提 | 前提となる状態 |
| When | ステップ | もし | 検証対象の操作 |
| Then | ステップ | ならば | 期待される結果 |
| And | ステップ | かつ/且つ | 直前ステップの継続 |
| But | ステップ | しかし/但し | 否定方向の継続 |
英語のFeatureには「Business Need」「Ability」という別名も登録されており、Example と Scenario、Scenario Outline と Scenario Template、Examples と Scenarios はそれぞれ完全な同義です。加えて、Given/When/Then/And/But のどれにも使える別名としてアスタリスクが登録されています。「* 商品「A100」がある」のように書け、列挙を並べるときにAndの連続を避けられます。記号系では、三重引用符とバッククォート3つがドキュメント文字列、縦棒がデータテーブル、アットマークがタグ、シャープがコメントを表します。
Feature・Rule・Scenarioの3層と1ファイル1Featureの制約
実際のファイルは次のように、Feature宣言を頂点にBackgroundとRule、その下にシナリオが並ぶ入れ子になります。
# features/cart.feature
Feature: ECサイトのカート
会員が在庫のある商品をカートへ入れて購入できること
Background:
Given 会員「tanaka」がログインしている
Rule: 在庫がある商品だけカートに入る
Example: 在庫のある商品をカートに追加する
Given 商品「A100」の在庫が 3 個ある
When 商品「A100」をカートに 1 個追加する
Then カートの点数は 1 になる
Example: 在庫切れの商品はカートに入らない
Given 商品「B200」の在庫が 0 個ある
When 商品「B200」をカートに 1 個追加する
Then 「在庫がありません」と表示される
公式リファレンスは「You can only have a single Feature in a .feature file.」と明記しています。テーマの違う仕様を詰め込むことはできず、機能が増えればファイルを分ける前提の設計です。Feature名やScenario名の下には自由記述の説明文を置けますが、説明文を終わらせる語は場所ごとに違います。Featureの説明文は Background・Rule・Example・Scenario Outline のいずれかの行で終わり、Scenarioの説明文は最初のステップ行で終わります。裏を返すと、Featureの説明文の途中に Given で始まる行を書いてもステップとして解釈されず、説明文のまま残ります。書いたはずのステップが実行されないときは、Backgroundより前に紛れ込んでいないか確認してください。
Given・When・Thenがステップ定義の照合に使われない仕様
公式リファレンスは「Keywords are not taken into account when looking for a step definition.」と述べています。Cucumberはステップを探すときキーワードを見ておらず、照合に使うのは後ろの文言だけです。したがって次の2行は、キーワードが違っても重複と判定されます。
Given there is money in my account
Then there is money in my account
帰結は2つです。1つは、Given/When/Thenの選択がテストの挙動を変えないこと。3語の使い分けは読み手のためのもので、間違えても実行結果は変わりません。もう1つは、状態を作る文と結果を確かめる文を同じ言い回しにしてはいけないことです。「残高が1000円である」を前提にも検証にも使い回すと、ステップ定義が1つに収束して意図しない実装が呼ばれます。前提側は「残高を1000円に設定する」、検証側は「残高が1000円と表示される」と、動詞まで含めて書き分けます。
BackgroundとRuleによる共通前提の集約
Backgroundは、後続の各シナリオの直前に毎回実行されるGivenの集合です。置き場所は最初のScenarioより前で、インデントは同じ階層に揃えます。実行順序はBeforeフックの後です。
公式リファレンスは「You can only have one set of Background steps per Feature or Rule.」としており、同じ階層にBackgroundを2つ並べることはできません。ただしRule単位でも置けるので、前提が2系統に分かれるならFeatureを分割する前にRuleで割ります。Feature直下とRule直下のBackgroundは併存し、Rule内のシナリオは両方を順に実行します。ログイン状態のような全体共通の前提を上、決済手段の設定のようなRule固有の前提を下に置きます。
複数条件・長文テキスト・タグを扱う補助構文の使い分け
同じ振る舞いを値だけ変えて何度も確かめたい、表や長い本文をステップに渡したい、CIで一部だけ流したい。この3つは補助構文でそれぞれ解決します。縦棒で書く表が2種類あるなど見た目が似ており、どれを選ぶかで保守性が変わります。
Scenario OutlineとExamplesテーブルによるパラメータ化
Scenario Outlineは値の入る位置を山括弧のプレースホルダで書き、Examplesの表から1行ずつ流し込みます。1つ以上のExamplesを必ず伴う必要があり、表の見出し行の名前がプレースホルダ名と対応します。
Scenario Outline: 購入数量に応じた送料判定
Given 商品「A100」を <数量> 個カートに入れている
When 送料を計算する
Then 送料は <送料> 円になる
Examples:
| 数量 | 送料 |
| 1 | 500 |
| 9 | 500 |
| 10 | 0 |
境界値を並べる用途に向いています。上の例なら、9個までは500円で10個から無料になる境界が表を見るだけで伝わります。逆に、条件ごとに期待結果の意味が変わる場合は使わないでください。「10個なら送料0円」「在庫切れならエラー」を1つの表に混ぜると、失敗時にどの仕様が壊れたのか読み取れなくなります。
データテーブルとドキュメント文字列のエスケープ規則
データテーブル(Data Tables)は1つのステップに表形式の値を渡す構文で、ドキュメント文字列(Doc Strings)は三重引用符で囲んだ長文を渡す構文です。どちらもステップ定義の最終引数になります。Examplesの表がシナリオを行数ぶん複製するのに対し、こちらは1回のステップ実行に値をまとめて渡します。
@checkout @smoke
Scenario: 複数会員への一括通知
Given 次の会員が登録されている:
| 氏名 | メール |
| 田中 | [email protected] |
| 佐藤 | [email protected] |
When 管理者が次の本文で通知する:
"""
メンテナンスのお知らせ
9月10日 2:00 から 4:00 まで停止します。
"""
Then 2通のメールが送信される
セル内で使えないように見える文字にもエスケープがあります。改行は \n、縦棒そのものは \|、バックスラッシュは \\ と書きます。ドキュメント文字列側は、開始の三重引用符の桁位置を基準に各行がデデントされます。開始位置より深いインデントは保持されるため、YAMLやJSONを渡すときはこの桁位置がそのまま値の意味を決めます。三重引用符の代わりにバッククォート3つも使えます。
タグによる実行対象の絞り込みとCI連携
アットマークで始まるタグは、Feature・Rule・Scenario・Scenario Outline・Examplesに付けられ、実行時のフィルタに使います。付けられない場所も仕様で決まっており、公式ドキュメントは「It is not possible to place tags above Background or steps」と明記しています。Backgroundやステップ行に書くとパースエラーになります。付けたタグは配下へ継承され、Featureのタグは Scenario・Scenario Outline・Examples に、Scenario Outlineのタグは Examples に引き継がれます。テストが増えたときに全件実行を避ける唯一の実用的な手段がタグです。@smoke の速度軸、@checkout のドメイン軸、@wip の状態軸を分けておくと、プルリクエスト時はスモークのみ、夜間は全件と切り替えられます。CI側の設定手順はGitHub Actionsでビルド・自動テストを設定する方法|CI/CDワークフローの作り方で扱っています。
日本語ロケールでGherkinを書く設定と対応キーワード
Gherkinは1行目に # language: ヘッダを置くことで、使用する自然言語を切り替えます。公式リファレンスは「A # language: header on the first line of a feature file tells Cucumber what spoken language to use」と説明しており、日本語なら # language: ja です。2026年9月時点で gherkin-languages.json には80言語の定義が入っています。
# language: ja
機能: パスワード再設定
背景:
前提 利用者「tanaka」が登録済みである
シナリオ: 登録済みメールで再設定リンクを受け取る
もし 「[email protected]」宛に再設定を申請する
ならば 再設定リンクを含むメールが1通届く
かつ リンクの有効期限は24時間である
シナリオ: 未登録メールでは送信しない
もし 「[email protected]」宛に再設定を申請する
ならば 「登録がありません」と表示される
しかし メールは送信されない
日本語定義には別名が複数登録されており、機能は「フィーチャ」、シナリオアウトラインは「シナリオテンプレート」「テンプレ」「シナリオテンプレ」、Examplesは「例」「サンプル」、Butは「しかし」「但し」「然し」「ただし」でも通ります。Ruleは「ルール」として登録済みです。注意点は、英語キーワードと日本語キーワードを1ファイル内で混ぜられないことです。公式は「ドメイン専門家が話す言語で書き、2言語間の翻訳は避けるべき」という立場を取っており、読み手が日本語話者なら日本語へ寄せたほうが結局は保守しやすくなります。
主要BDDフレームワークのGherkin対応と選定基準
Gherkinは言語仕様で、実行するのは各言語のフレームワークです。同じ .feature が読めるとは限らず、特にRuleは対応時期に差があります。2026年9月5日時点の各レジストリで確認した状況は次のとおりです。
| フレームワーク | 言語 | 最新版 | Rule対応 | 確認元 |
|---|---|---|---|---|
| Cucumber-JVM | Java | 7.34.7 | 対応 | Maven Central |
| cucumber-js | JavaScript/TypeScript | 13.2.1 | 7.0.0以降 | npm registry |
| behave | Python | 1.3.3 | 1.3.0以降 | PyPI |
| pytest-bdd | Python | 8.1.0 | 8.0.0以降 | PyPI |
| Reqnroll | C#/.NET | 3.3.4 | 対応 | NuGet |
| cucumber-rs | Rust | 0.23.0 | 対応 | crates.io |
JavaでのCucumber導入手順と実際のステップ定義の書き方はCucumberとは?Javaでのテスト自動化とGherkin記法の書き方を実例で解説にまとめています。Spring Bootアプリに組み込む場合は cucumber-spring を追加し、@CucumberContextConfiguration を付けたクラスでコンテキストを結び付けます。Pythonでpytest-bddを選ぶなら、既存のfixtureやパラメータ化の資産をそのまま使えるかが判断材料になります(pytestの使い方・書き方を徹底解説|インストールからfixture・パラメータ化まで)。
Rule対応の可否で分かれるフレームワークの世代差
Ruleは「The (optional) Rule keyword has been part of Gherkin since v6.」とありGherkin v6で追加され、cucumber-jsは2020年9月14日のリリース候補7.0.0-rc.0で取り込み、安定版の7.0.0は同年12月21日に出ています。一方Pythonの2つは長く未対応でした。pytest-bddがRuleを扱えるようになったのは2024年11月14日の8.0.0で、同じリリースで # language: によるローカライズにも対応しています。behaveは2018年2月の1.2.6が7年以上も最新版のままで、Ruleを含む構文の刷新が届いたのは2025年8月の1.3.0でした。
この差が効くのは、複数言語でテストを書いているチームです。Java側でRuleを使った .feature を書き、同じファイルをPython側で流用してパースエラーになるのが典型的な事故です。既存プロジェクトのbehaveが1.2.6で止まっているなら、Ruleを使う前にバージョンを確認してください。1.2.6と1.3.0の間にはタグ式の仕様変更も入っており、上げるなら構文とタグ表現を同時に見直すことになります。
SpecFlow終了後のReqnroll移行の判断材料
.NET環境は選択の余地がほとんどありません。Reqnrollの告知は「In December 2024, Tricentis announced the end-of-life of the SpecFlow open source project.」「SpecFlow reached its end-of-life on December 31, 2024.」と述べ、翌1月1日にSpecFlowのGitHubプロジェクトが削除されたことも記しています。NuGet上もSpecFlow本体は4.0.31-betaというプレリリースで止まったままです。
したがって新規の.NETプロジェクトでSpecFlowを選ぶ理由は無く、Reqnrollを使うべきです。移行については、公式ガイドが .feature ファイルは変更不要としています。作業の中心は、SpecFlow系NuGetパッケージを Reqnroll.NUnit 等へ差し替え、名前空間 TechTalk.SpecFlow を Reqnroll に置換することです。加えて設定を reqnroll.json へ移し(stepAssemblies は bindingAssemblies に改名)、SpecFlow v3からの破壊的変更でステップ定義の async void が禁止されたため async Task へ直します。互換パッケージ Reqnroll.SpecFlowCompatibility で名前空間の置換は先送りできますが、設定と非同期まわりの修正は避けられません。
Gherkinを採用すべきでない場面と破綻の分かれ目
Gherkinは万能ではありません。導入しても誰も .feature を読まなくなり、ステップ定義の保守コストだけが残る構図に陥りやすい仕組みです。分かれ目は「非エンジニアが実際に読んで指摘するか」の一点にあります。プロダクトオーナーもQAも .feature を開かず開発者だけが書いているなら、各言語のテスティングフレームワークで直接書いたほうが速く、壊れにくくなります。生成AIに .feature を書かせる場合も同じで、レビューする読み手がいなければ平文で書く利点は消えます。BDDそのものを導入すべきか迷う段階なら、BDDとは?振る舞い駆動開発の仕組みとTDDとの違い・導入判断を実装者向けに解説で判断基準を確認してください。
画面操作手順をステップに写したシナリオの破綻点
典型的な失敗が、シナリオを画面操作の手順書として書いてしまうパターンです。「ログインボタンをクリックする」「メールアドレス欄に入力する」といったステップを並べると、その .feature は特定のUI実装に固定されます。ボタンの位置が変わっただけで全シナリオを直すことになり、直すのは文言なのでステップ定義の再マッピングまで発生します。
Whenに書くべきは、利用者が達成しようとしている出来事です。「ログインする」「再設定を申請する」のように、画面が変わっても意味が変わらない粒度に上げます。UI要素の特定はステップ定義の実装側、Seleniumの使い方|Selenium 4でWebDriverの手動設定が不要になった書き方で扱うようなドライバのコードに閉じ込めてください。この境界が守れているかが、1年後に .feature が残るかを決めます。
シナリオ増加に効くタグ設計とディレクトリ分割
シナリオが数百件に達すると、実行時間よりも先に「どこに何が書いてあるか分からない」ほうが問題になります。1ファイル1Featureの制約は、この点ではむしろ有利に働きます。ディレクトリをドメイン単位で切れば、仕様の所在がパスから分かるからです。
実行の切り口はタグに寄せます。ディレクトリは仕様の住所、タグは実行の観点と役割を分けておくと、後から「決済まわりのスモークだけ流す」という要求にファイル移動なしで応えられます。タグは配下へ継承される仕様なので、Featureに1つ貼れば全シナリオに効きます。増やすなら、速度軸・ドメイン軸・状態軸の3系統から外れるタグは足さないと決め、READMEに一覧と意味を残してください。
よくある質問
Gherkin形式(Gherkinフォーマット)とは何ですか?
Gherkin形式は、Given/When/Thenを中心としたキーワードで、システムの振る舞いを行単位で記述する仕様記述フォーマットです。拡張子 .feature のプレーンテキストとして保存し、Cucumberなどのフレームワークが解析して、各ステップに対応するコード(ステップ定義)を実行します。仕様書と自動テストを1つのファイルで兼ねられる点が、通常のテストコードとの違いです。
Given-When-Then形式とは何ですか?
1つのシナリオを「前提となる状態(Given)」「起きる出来事(When)」「期待される結果(Then)」の3段で書く型です。Gherkinはこの型をキーワードとして言語に組み込んでいます。ただしCucumberはステップを探す際にキーワードを見ないため、3語の使い分けは実行結果ではなく可読性のためのものです。
Gherkinは「ガーキン」と読みますか?
はい、日本語では一般に「ガーキン」と表記します。元はピクルスにする小型のキュウリを指す英単語で、Cucumber(キュウリ)というフレームワーク名にちなんだ命名です。そのため検索結果には食品や、ロンドンの同名の建築物に関する情報も混在します。技術文脈で調べる場合は「gherkin 記法」「gherkin bdd」のように語を足すと絞り込めます。
1つの.featureファイルに複数のFeatureを書けますか?
書けません。公式リファレンスが1ファイル1Featureと明示しており、2つ目のFeature行はパースエラーになります。関連する複数の仕様をまとめたい場合は、Featureの中をRuleで区切るか、ファイル自体を分けてディレクトリでグルーピングしてください。Ruleで区切る場合も1ファイル内のFeatureは1つのままです。ディレクトリをドメイン単位で切り、ファイル名をFeature名に対応させておくと、仕様の所在をパスから追えます。
GherkinとEARS記法はどう使い分けますか?
Gherkinは具体例ベースで、1シナリオが1つの実行可能なテストに対応します。対してEARS記法は、要求そのものを定型文パターンで曖昧さなく書くための構文で、実行はしません。上流の要求定義をEARSで固め、そこから導かれる受入条件をGherkinで具体例に落とす、という順で併用する形が噛み合います。EARS側の書き方はEARS記法とは?6つの型と書き方・実例をKiro連携まで解説を参照してください。