現在、Turnipを使って、あるアプリの Endo-to-Endテストを書いてます。
ご存知の通り、Turnip は Cucumber同様に 自然言語に近い Gherkin 形式でテストが書けるツールです。
Gherkin記述の featureファイルを 実際に Endo-to-Endテストを実行する Capybara API に変換する部分は steps というところにRubyのコードを書きます。
- feature
機能: モンスターを攻撃する 前提: モンスターがいる シナリオ: モンスターを攻撃する もし それを攻撃したら ならば それは死ぬ
- steps
step "モンスターがいる" do @monster = Monster.new end
steps の分割
テスト(feature)が大きくなると、当然 steps も大きくなります。
また違う意味の同じ名前(文字列)のsteps を書いてしまったりして困ります。 例えば、 "完了ボタンを押す" という steps が画面によって機能が違うことがあります。
そんな時のために、Turnipには Scoped steps というモジュール化機能があります。 これを使って、steps を機能ごとに分割したりできます。
- steps
steps_for :shopping do step "完了ボタンを押す" do ... end end steps_for :customer do step "完了ボタンを押す" do ... end end
- feature
@shopping もし 商品をカートに入れ かつ 完了ボタンを押す
- feature
@customer もし 名前に "吉田だれ" と入力 かつ 完了ボタンを押す
素晴らしい〜!
steps を共有したい場合
Webアプリの画面は基本的には機能別になっていますが、別の機能へのリンクや別の情報表示で、他の機能用に作った steps を使いたくなる事が多々あります。
Scoped steps を使い、他の機能のテスト(feature)からも使われる steps (例えば shopping_public)と その機能専用の steps (たとえば shopping)を分けて featureには必要となる steps を明記する方法も考えられますが、
- feature は多数になるので、毎度必要な steps を複数書くのはだるい
- 一般的には shopping steps の中でも shopping_public のstep を呼び出し事す事が良くある → Calling steps from other steps
Scoped stepsは ドキュメント にあるように Ruby言語の module で書けます、という事は include できます。
そこでこんな風に step を書くと feature には1つ書くだけで、他の steps を共有ができるようになります。
- shopping_steps.rb
module ShopingPublic step "ショッピングカート内容が表示される" do .. end end require 'steps/customer' steps_for :shopping do include ShopingPublic include CustomerPublic ... end
- customer_steps.rb
module CustomerPublic step "ログイン者の情報が表示される" do .. end end steps_for :customer do include CustomerPublic ... end
- shopping.feature
@shopping もし ユーザー情報リンクをクリック ならば ログイン者の情報が表示される
このやり方がベストだとは思っていますが、今のところうまくいってます。