Gherkin記法(読み方:がーきん)は、ビジネスロジックや動作をテストする際に使われる人間にも読みやすいテキスト形式の言語。テスト自動化ツールであるCucumberや、当サイトでも触れたKarateで使われています。
Gherkin記法は、特にビヘイビア駆動開発(Behavior-Driven Development, BDD)というプロセスでよく用いられます。
- Qビヘイビア駆動開発(BDD)とは?
- A
簡単に言えば「ソフトウェアがどのように振る舞うべきかを明確にして、その振る舞いをテストすることで開発を進める方法」。開発するアプリやシステムがどんな機能を持っていて、どのように動作するのかを技術的な詳細に入る前に、シンプルな言葉でみんなが理解できる形でまとめておくこと。そして、その振る舞いを確かめるテストを先に作ってから、そのテストに合格するようにプログラムを書いていくのがビヘイビア駆動開発(BDD)。
Gherkinの目的
Gherkinの目的は「みんなで同じストーリーを共有して、誰もが理解できるように、テストシナリオをお話し形式で書くこと」です。要するに「プロジェクトに関わる全員が、どんなテストをしているのかを簡単に理解できるように」しておくことで、技術的な背景がない人でもテストの内容を見て何が確認されているのかがすぐに分かるようにしておくことがGherkinの目的。
要はわかりやすい書き方でテストの内容を整理するための記法がGherkinだと理解すればOK。
Gherkinの特徴と構造
Gherkinは非常にユーザーフレンドリーな言語でアプリのテストを「物語」のように書くことができるため、プロジェクトに関わるすべての人々がテストの内容を簡単に理解できるようになるという特徴があります。
早速、その特徴とGherkinの基本について1から見ていきましょう。
特徴
- 自然言語に近い形式:Gherkinは英語や日本語などのような自然言語に非常に近い形式で書かれます。結果、技術的な知識がない人でもテストの内容を理解しやすくなります。
- シナリオベース:テストは「シナリオ」という形式で書かれます。これはある特定の機能がどのように動作すべきかの具体的な例を示しています。
- コミュニケーションツールとしての利用:Gherkinは単なるテストスクリプトとしてだけではなく、プロジェクトチーム内のコミュニケーションを促進するツールとしても機能します。
ざっくりとした概要は上記の通り。具体的なコードを見ながらイメージを深めていきましょう。
構造
Gherkinの文書のサンプルを先にお見せします。このサンプルをベースにGherkin記法の概要をご説明していきます。
サンプルコード Gherkin
Feature: 商品の検索機能 顧客が商品を簡単に見つけられるようにする。 Background: Given ユーザーがログインしている Scenario: 商品名での検索 When ユーザーが「スニーカー」で検索する Then 検索結果に「スニーカー」が表示される Scenario: カテゴリでの検索 When ユーザーがカテゴリ「アクセサリー」を選択する Then 検索結果にアクセサリー関連の商品が表示される
各部分の説明
- Feature(機能)
- 概要: Featureパートでは「商品の検索機能」というテストする機能の名前。その機能についての簡単な説明が記されています。
- ポイント: どんなテストなの?ってのが理解しやすい名前であればOK。
- Background(背景)
- 共通の前提条件: テスト実行時の前提条件を設定します。ここでは「ユーザーがログインしている」という条件が設定されています。
- Scenario(シナリオ)
- シナリオ1: 「商品名での検索」という具体的なテストケース。
- When: ユーザーが「スニーカー」で検索。
- Then: 検索結果として「スニーカー」が表示されることを確認。
- シナリオ2: 「カテゴリでの検索」という別のテストケース。
- When: ユーザーがカテゴリ「アクセサリー」を選択。
- Then: 検索結果にアクセサリー関連の商品が表示されることを確認。
- シナリオ1: 「商品名での検索」という具体的なテストケース。
Featureでテストの目的を宣言。Backgroundで共通の前提条件を設定し、個々のシナリオで具体的なテストケースを記述するというのがGherkin基本の概要です。
ここからはより詳細にGherkin記法の基本ルールをご説明していきます。
Gherkin記法の基本ルール
Gherkinの基本文法と使用法を初心者向けのカリキュラムとして整理しました。ここでは、Gherkinで使う主要な要素とそれらがどのように機能するかを1つ1つ順を追ってご説明します。
インデント
Gherkinではインデント(字下げ)は任意。基本的に可読性を向上させるためだけに使用されます。シナリオ内のステップ(Given
, When
, Then
, And
, But
)は同じレベルのインデントとすることで、テストの内容を構造的に理解しやすいようにするのが一般的。
またFeature
, Scenario
, Background
などのキーワードは通常、行の先頭から始めるのが主流です。
コメント
Gherkinでは#
記号を使用してコメントを追加できます。コメントは行のどの部分からでも始めることができ、その行の残りの部分は無視されます。
Gherkinにおけるコメントは一般的なプログラミング言語と同様に、コードの特定の部分を説明するためだったり、一時的にコードを無効にするために使用されます。
空行
空行はGherkinファイル内で自由に使用可能で、シナリオやステップのグループ間に視覚的なスペースを提供するのに役立ちます(インデントと同じで読みやすくするために利用されます)。空行をうまく利用することで、大きなファイルの可読性が向上します。
空行は解析時に無視されるため、ファイルの動作に影響を与えません。
特殊文字
Gherkinファイルは通常、UTF-8エンコーディングを使用して記述されるため、さまざまな言語でキーワードやテキストを書くことができます。テキスト内のデータを引用するために二重引用符(")やシングル引用符(')を使用することがありますが、これも必須ではありません。
サンプルコード インデント、コメント、空行の使用方法
# Featureの説明 Feature: ユーザー認証 # Backgroundの説明 Background: Given ユーザーがログイン画面にアクセスしている # Scenario 1 Scenario: 有効なユーザー名とパスワードでログイン When ユーザーが「username」と「password」を入力 And ログインボタンをクリックする Then ユーザーはダッシュボードにリダイレクトされる # Scenario 2 Scenario: 無効なユーザー名でのログイン試行 When ユーザーが「invaliduser」と「password」を入力 And ログインボタンをクリックする Then エラーメッセージが表示される
Gherkin記法の基本キーワード
Gherkin記法の基本的なキーワードとその用途を以下に整理します。この辺の内容をある程度頭に入れておけば、きっとFeartureファイルを読むことでなんとなくその中身を理解することができるようになるでしょう。
キーワード | 説明 |
---|---|
Feature | テスト対象の機能の説明を行うパート。ドキュメントのタイトルや、テストの目的を簡潔に述べるために利用。 |
Scenario | 個々のテストケース。シナリオは具体的なユーザーストーリーや要件をテストするために用いられる。 |
Given | テストの前提条件。特定のテストが開始される前の状態やコンテキストを明確にする。 |
When | テスト中に行われるアクションやイベントを記述する。ユーザーやシステムが何を行うかを示す。 |
Then | 期待される結果。Whenで定義されたアクションの結果、システムがどのように反応すべきかを記述。 |
And | 前のGiven、When、またはThenが複数のステップや条件を持つ場合に使用する。シナリオ内での論理的な接続を提供する。 |
But | 前のGiven、When、またはThenに対する例外や対照的な条件を追加するために使用する。通常、期待される結果に対する例外を記述する際に利用される。 |
Background | 複数のシナリオで共通の前提条件を一度に設定するために使用される。シナリオの冗長性を減らし、コードの再利用を促進する。 |
Examples | シナリオアウトライン内で使用され、複数の入力値や期待値をパラメータとしてテストを多変数化するためのデータテーブルを提供する。 |
Scenario Outline | 一連のステップをテンプレートとして定義し、Examplesセクションに記載された異なるデータセットを使用して複数回実行するシナリオ。 |
サンプルコード 商品の検索機能のテスト
# 機能の説明: 商品の検索機能をテストします。 Feature: 商品検索機能 # すべてのシナリオで共通の前提条件 Background: Given ユーザーが商品検索ページにアクセスしている # シナリオ1: 正しいキーワードで商品を検索 Scenario: 正しいキーワードで商品を検索する When ユーザーが「スニーカー」を検索ボックスに入力して検索ボタンをクリックする Then 検索結果に「スニーカー」が含まれる商品が表示される # シナリオ2: 空のキーワードでの検索試行 Scenario: 空のキーワードでの検索試行 When ユーザーが空の検索ボックスで検索ボタンをクリックする Then 検索結果は表示されず、エラーメッセージが表示される
サンプルコード ユーザーログイン機能のテスト
# 機能の説明: ユーザーログイン機能をテストします。 Feature: ユーザーログイン機能 # 背景: ログイン前の共通の設定 Background: Given ユーザーがログインページにいる # シナリオ: 有効なユーザー情報でのログイン Scenario: 有効なユーザー情報でログイン When ユーザーが有効なユーザー名とパスワードを入力してログインボタンを押す Then ユーザーはダッシュボードにリダイレクトされる And ログアウトボタンが表示される # シナリオ: 無効なユーザー情報でのログイン試行 Scenario: 無効なユーザー情報でログイン試行 When ユーザーが無効なユーザー名とパスワードを入力してログインボタンを押す Then ログインは失敗し、エラーメッセージが表示される
サンプルコード シナリオアウトライン
# 機能の説明: ログイン機能のさまざまなシナリオをテストするためのパラメータ化されたテスト Feature: パラメータ化されたユーザーログインテスト # シナリオアウトライン: 異なるユーザー情報でのログインテスト Scenario Outline: 異なるユーザー情報でのログイン Given <user>がログインページにアクセスしている When <user>がユーザー名「<username>」とパスワード「<password>」を入力し、ログインボタンを押す Then <user>は<result>にリダイレクトされる # 例: 具体的なユーザー名とパスワード、及び期待される結果 Examples: | user | username | password | result | | Alice | alice101 | pass123 | ダッシュボード | | Bob | bob202 | wrongpass | エラーページ |
APIテスト自動化ツール:karateでのGherkin記法
KarateはGherkin記法を利用してAPIテストを簡単に記述できるフレームワーク。以下にいくつかのKarateの使用例を示しますが、これらの例はKarateがGherkin記法をどのように利用・応用しているかをわかりやすく説明しています。
サンプルコード APIのステータスコードとレスポンス検証
Feature: ユーザー情報の取得APIテスト Scenario: 特定のユーザーの情報を取得 Given url 'https://api.example.com/users' And path '123' When method get Then status 200 And match response == { id: 123, name: 'John Doe', status: 'active' }
このシナリオでは、指定されたURLにGETリクエストを送信し、HTTPステータスコードが200であること、そしてレスポンスボディが期待されるJSONオブジェクトと一致することを検証しています。
サンプルコード 複数のAPIリクエストとレスポンスデータの使用
Feature: 複数のAPIを連携してテスト Background: * url 'https://api.example.com/' Scenario: ユーザーデータを取得して注文履歴を確認 Given path 'users', '123' When method get Then status 200 And def userId = response.id Given path 'orders' And param user = userId When method get Then status 200 And match each response.orders contains { productId: '#number', quantity: '#number' }
この例では、まずユーザー情報を取得し、そのレスポンスからユーザーIDを抽出しています。その後、抽出したユーザーIDを使用してそのユーザーの注文履歴を取得し、各注文が特定の形式であることを検証しています。
サンプルコード 複雑なデータ検証
Feature: 製品情報の詳細検証 Scenario: 製品の詳細情報を検証 Given path 'products', '456' When method get Then status 200 And match response == { id: 456, name: 'Smartphone', price: '#regex[0-9]+', available: true }
ここでは特定の製品IDで製品情報を取得し、レスポンスが期待される属性を持っているかどうかを検証しています。価格が数字であることを正規表現を使って検証しています。
これらの例は、KarateがGherkin記法を用いて、テストシナリオの記述を直感的で読みやすくする方法を示しています。Karateの強力な機能を使って、APIテストを効率的に自動化することができます。