Turnip とは
feature spec を Gherkin で記述するためのライブラリ
https://github.com/jnicklas/turnip
↓ こんな感じ
# spec/features/exam.feature
# encoding: utf-8
Feature: テスト管理
@teachers
@exams
Scenario: 学習スケジュールが無い小テストを編集できる
Given 先生がログインする
Given 1-1 クラスを用意
Given 2018-07-01 に小テストを用意
When サイドバーのスケージュール管理からクラス一覧に移動
When 1-1 クラスのスケージュールをクリック
When 2018-07-01 の 1 ~ 20 をクリックする
Then 学習日が0日と表示されている
When 編集をクリックする
When 試験日に 2018-07-01 を入力して更新をクリック
Then 詳細パネルに 2018-07-01 が日本語表記で表示されている
Then 学習日が0日と表示されている
# spec/steps/exam_steps.rb
steps_for :exams do
step ':class_name クラスのスケージュールをクリック' do |class_name|
school_class = SchoolClass.find_by!(name: class_name)
within "#cy-school-class-#{school_class.id}" do
click_on 'スケジュール'
end
end
step ':date の :start ~ :end をクリックする' do |date, start, _end|
within "#cy-schedule-#{date}" do
click_on "#{start} ~ #{_end}"
end
end
step '学習日が0日と表示されている' do
within '#cy-study-schedules' do
expect(page).to have_content 'テストまでの学習日(0日)'
end
end
step '編集をクリックする' do
within '.content-wrapper' do
click_on '編集'
end
end
step '試験日に :date を入力して更新をクリック' do |date|
fill_in_date_picker('試験日', Time.zone.parse(date).to_date)
click_on '更新'
end
step '詳細パネルに :date が日本語表記で表示されている' do |date|
within '#cy-exam-detail' do
expect(page).to have_content Time.zone.parse(date).to_date.strftime('%Y年%m月%d日')
end
end
end
Gherkinとは
feature ファイルの記述方式, 及びそのパーサなどの gem
もとは Cucumber で使われていたものが gem に切り出されたらしい
上の例で言うと test.feature
がそう
Feature
や Scenario
, Given
などの予約語の後に自然言語で定義されてたステップを指定するとそれが実行される
通常の spec ファイルよりも操作の流れがわかりやすく, 非エンジニアでも読むことができる
(正しい解説 -> https://docs.cucumber.io/guides/overview/#what-is-gherkin)
Cucumberとは
受け入れテストの feature spec を書きやすくするためのオープンソースのもの(java とかでも使えるらしい)
step の定義方法に正規表現を使う
turnip はこれを元につくられた(要出典)
# steps/teacher_steps.rb
When /^先生がログインする$/ do
fill_in "Email", with: @user.email
fill_in "Password", with: @user.password
click_button "Sign in"
end
When
や Then
などの予約語には対応する日本語を使用できる(例↓出典)
日本語の予約語を使用する場合は実行オプションに -l ja
を付けるか # language: ja
をファイルに記述する必要がある
# language: ja
フィーチャ: ユーザ一覧画面
シナリオ: ユーザ一覧画面を表示
前提 ユーザ数が 3 件登録されている
もし ユーザ一覧画面を表示する
ならば 1 件のユーザ情報が表示されること
$ cucumber --i18n-language # 使用できる言語表
$ cucumber --i18n-keywords ja # その言語での予約語の対応表
turnip とは
正規表現の複雑さを排除した cucumber
capybara と同じ人が開発している*1
cucumber と同様に日本語の予約語を使用できる
spec と一緒に実行できる (spec 実行時 -r turnip/rspec
オプションをつける)
導入方法
必要な gem は turnip のみ(ただし, すでにcapybara での feature spec 環境がある前提)
-
spec/turnip_helper.rb
を用意 -
spec/features/
に feature ファイル とspec/steps/
に steps ファイル を用意 - 実行
bundle exec rspec -r turnip/spec [feature ファイルパス]
spec/turnip_helper.rb
を用意
turnip では rails_helper ではなく turnip_helper を読みに行くので用意
rails_helper に設定を書いている場合は ここで require
Dir[Rails.root.join('spec/steps/**/*_steps.rb')].each { |f| require f }
は公式では require
ではなく load
を使っていますが私の環境だと hpricot_slate_method_added
で NoMethodError になった後 Segmentation fault でだめでした. (ちゃんとしらべてないので要検証)
require 'turnip'
require 'turnip/rspec'
require 'turnip/capybara'
require 'rails_helper'
Dir[Rails.root.join('spec/steps/**/*_steps.rb')].each { |f| require f }
spec/features/
に feature ファイル と spec/steps/
に steps ファイル を用意
一番上の例のように, feature ファイルと steps ファイルを用意する
通常の feature spec の操作一つひとつに名前を付けて step にする感じで良いと思います
一番上の例だとグローバルに step を定義していますが, module でくくってから RSpec.configure { |c| c.include MonsterSteps }
のように include
するほうが推奨らしい (要出典)
詳しい下記書き方は github を参照
実行 bundle exec rspec -r turnip/spec [feature ファイルパス]
考察
メリット
feature が自然言語で読めるので, ディレクターやマネージャーでもテストケースが確認できる
スプレットシートでテストケースを管理しているようなところでは, feature に落としこんで確認するとかができそう
GUI で確認できたらなお良い(そういうのがあるのかは要調査 (簡単なのならすぐ作れそう?))
TDD がやりやすそう
タスク切る際に, feature だけ作っておいて, 実装者が steps を書くような運用になるのか?(要検討)
すでに feature spec をやっているなら導入が楽
移行も難しくはない
デメリット
RubyMine で実行(run)できない
これが一番大きい気がする
Cucumber なら実行可能
もちろん RubyMine のコンソールからなら実行可能
変数のコントロールがしにくい
試していないですが, feature では変数を持てない(多分)
上の例のように, step 内で インスタンス変数を作ってそれを回すようなイメージ
feature からは値決め打ちの記述になる (よくある 先に factory で build して値をフォームに入れるようなやり方がしにくい)
ただ, これに関しては feature を読んで何をやっているかわかるためのものなのでそれでいい気がする
(乱数での値生成もやるべきではない?)
結局 capybara の api を使うのでそれからは逃げられない
逆に capybara ができれば大丈夫ということでもある
非エンジニアでもよめるとはいえ github なりでソースを読む必要がある
そういうふうにつかうのであればもう一つなにかをかませる必要がありそう(Web GUI から fearture が閲覧, 編集ができるようにするなど)
感想
RubyMine で実行できるなら全力でつかってた