Cucumber 利用していますか?
基本的な使い方はわかるんだけど、なんだかもっと上手く使えるんじゃないだろうか?と、もやもやしながら使っています。 少くとも私の周りには Cucumber について情報交換できる人がいないです。
それでも、SlideShare や Speaker Deck なんかに公開されたスライドでよくみかけるので、使い込んでるところでは使い込まれているのだと思います。
Cucumber は Rails プロジェクト以外でも利用されているようで、範囲が広いです。もうちょっといろんな情報がWeb上に流れていても良い気がします。
私が知る限りでは Cucumber についてもっと詳しく書かれているのは The Rspec Book です。
前置きはさておき、 Cucumber の *.feature
は Gherkin という 言語で書きます。
その文法について調べたのでそのメモを整理しておきます。
ちなみにこの内容はソース読んだり、Wikiに書かれているものを参考したもので、仕様として記述されてない情報もあるので未来のバージョンでは予告なく変更される部分があるかもしれません。
こんな長くて不正確な記事読みたくないよ!という人は BNF を読むのが手っ取りです。 というか、BNFが読める人は読みましょう。 むしろ、もっとはやく読めばよかった。
具体例
Gherukinのという言語で書いた文書の例を上げておきます。 内容はシステムに関するものにしませんでした。
# language: ja
@blog
フィーチャ: ブログを書く
ブログを書くには本人のやる気と書く時間が必要です。
アウトプットは次のインプットに繋がるので積極的に行なうべきです。
# これはコメントでタグの後にはかけない
# @ではじまるのはタグ
@good
シナリオ: ブログが書ける
ブログが書ける場合はやる気と時間があるのです。
# ネタがないとかけないです。
前提 ネタがある
# 時間がないとかけないです
かつ 納期に終われていない
# 先輩とかいないですけど
もし 先輩にブログを書けと言われた
# オチがない
ならば ブログが書けている
@bad
シナリオ: デスマ中はブログが書けない
デスマ中ダトソレドコロジャナインダ!!
前提 ネタがある
かつ デスマ中
もし 先輩にブログを書けと言われた
ならば ブログが書けていない
見てわかるように、ほぼ自然言語の雰囲気を残せます。 これならプログラマ以外の人でも読み書きできそうだよね。 ってのがウリです。
要素
Gherkin は以下の要素で構成されます。 ここでは要素と呼んでますが、トークンの一部を抜粋しただけです。
- コメント
- タグ
- フィーチャ
- バックグラウンド
- シナリオ
- シナリオテンプレート
- 例
- ステップ
- ドックストリング
- 表
トップダウンに説明していきます。説明する前の用語がでてきますが、一通り読んでもどってくると良いです。
ファイル構成
Gherkin では ひとつのファイルにひとつのフィーチャ
しか記述できません。
なので全体像としては
コメント
(省略可能)タグ
(省略可能)フィーチャ
となります。
タグ
とコメント
の順番は入れかえることはできません。
具体的には:
# comment
@tag
フィーチャ: フィーチャ名
コメント
#
ではじまる行は コメントになります。
#` の前に空白があっても構いません。
プログラミング言語にあるような
@blog # comment
のようなことはできません。
先頭にある language: ja
は特殊なコメント
でこのファイルで使用するキーワードの言語を指定します。
フィーチャ
や シナリオ
,前提
、かつ
などがキーワードです。
コメント
は書けるところがわりと限られてます。
タグ
@ではじまる単語は タグになります。 1行に複数かくこともできますし、複数行にわたってかくこともできます。
@blog @hoge
@mogu
フィーチャ
やシナリオ
の前で書けます。
フィーチャ
このファイルに記述するフィーチャ
(機能)に関して記述します。
言語に日本語を利用している場合は
フィーチャ:
または 機能:
ではじまります。
つづけてその後ろには、そのフィーチャ
の名前をかきます。
次の行にはフィーチャ
に関する説明をかくことができます。
説明はだいたい好きなように書けます。
それ以降にはバックグラウンド
とシナリオ
を n個かくことができます。
フィーチャ
: 名前説明
(省略可能)バックグラウンド
(省略可能)シナリオ1
orシナリオアウトライン
シナリオ2
orシナリオアウトライン
- .
- .
- .
シナリオn
orシナリオアウトライン
フィーチャ
と説明
の間には空行は置けますがコメント
などは書けません。
具体的には:
フィーチャ: フィーチャ名
フィーチャの説明
バックグラウンド:
前提 なにかがある
シナリオ: シナリオ名
.
.
.
のような感じです。
フィーチャ: hoge
説明
# comment
説明
などはエラーになります。
バックグラウンド
フィーチャ
内のシナリオ
の前に実行したいステップ
をかくことができます。
- 背景: 名前
- ステップ1
- ステップ2
- .
- .
- .
- ステップn
という構造になります。
シナリオ
シナリオ
はひとつのテストになります。
シナリオ
はステップを複数持っていて、ステップ
の途中で失敗するとシナリオは失敗したことになります。
シナリオ
もフィーチャ
と同様に説明が書けます。
コメント
(省略可能)タグ
(省略可能)シナリオ
: 名前説明
(省略可能)ステップ1
ステップ2
- .
- .
- .
ステップn
という構造になります。
シナリオアウトライン
シナリオ
の重複を減らすためにはシナリオアウトライン
を使うことができます。
シナリオ内に変数を埋めこんで、最後に変数に代入する値を例
として明示することで、シナリオ
になります。
変数は <変数名>
として表現できます。
- コメント(省略可能)
- タグ(省略可能)
- シナリオアウトライン: 名前
- 説明
- ステップ1
- ステップ2
- .
- .
- .
- ステップn
- 例:
- 表
具体例をあげておきます。
シナリオアウトライン: <種類>が書ける
<種類>が書ける場合はやる気と時間があるのです。
前提 ネタがある
かつ 納期に終われていない
もし <人>に<種類>を書けと言われた
ならば <種類>が書けている
例:
| 種類 | 人 |
| ブログ | 先輩 |
| 資料 | 営業 |
例の表の 1行目は変数名に対応しますが、Gherkinというより Cucumber の部分になる気がします。 2行目に具体的な値を書きます。
ブログ が <種類> の部分に、先輩 が <人> の部分に 展開されます。
シナリオアウトライン
の代わりに シナリオテンプレート
なども使えます
詳細は
$ cucumber --i18n ja
ステップ
先頭が前提
もし
ならば
などの部分です。
Cucumberでは対応する コード が実行されます。
コメント
(省略可能)ステップキーワード
: 名前ドックストリング
もしくは表
(省略可能)
という構造になります。
ステップキーワード
には
- 前提 (given)
- もし (when)
- ならば (then)
- かつ (and)
- しかし (but)
などがあります。
*
というのもありまして:
* ネタがある
* 納期に終われていない
* 先輩にブログを書けと言われた
* ならば ブログが書けている
とかいても等価です。
cucumber --i18n ja
なども確認してみてください
ドックストリング
ステップに長い文字列を渡したい場合に利用します。
'''
(クオート3つ)で挟むことでドックストリングになります。
前提 ネタがある
'''
デスマ神がほげほげ
ネコ型の何かがもぐもぐ
'''
かつ 納期に終われていない
とすると “ネタがある” ステップ
ヘ “デスマ神がほげ…もぐもぐ” という文字列を渡すことができます。
表
表は “シナリオアウトライン
の例” と “ステップ
への引数として表を使いたい” 場合に利用できます。
表は|
(パイプ)を利用してAscii Art で表を書きます。
シナリオアウトライン
についてはもう書いているので省きます。
ステップ
で使用すると Cucumber::Ast::Table
というクラスのインスタンスが渡されます。ステップの実装で煮るなり焼くなりしあしょう。
一応具体例:
前提 なにかある
| 1 | 2 |
| 3 | 4 |
もし なにかする
| 1 | 2 | 3 |
| 4 | 5 | 6 |
ならば こういう結果になる
| 7 | 8 | 9 | 10 |
インデントについて
インデント自体に意味はありませんが適切につけておくと読みやすいです。cucumberで実行した場合は自動的に整形されます。
まとめ
無駄に時間がかかりました。何かの役に立てば良いなぁ。 途中で対象読者を意識してないことに絶望していろいろブレてます。
間違いなどあればご連絡ください。
仕事してきます。