日本語で結合(総合)テストが書けるcucumberを触ってみました。
form入力の動作をラベル名で指定できたり、表形式でのデータ表現はとてもいいと思いました。
いきなりガシガシ書けるというモノでは無いので
日本語で書くことを理解するために自動生成されるテストを
日本語に変更してみました。
なので、以下実践的な内容ではありません。
scaffold程度の画面では不要で、もっと複雑なシナリオの方が向いていると思います。
インストール
Ruby on Rails - cucumber - GitHub
rails で使うには、cucumber-railsが必要です。
また、moroさん作成のmoro-miso(もろ味噌)も入れましょう。
$ sudo gem install cucumber $ sudo gem install cucumber-rails $ sudo gem install moro-miso
$ rails blog $ cd blog $ ruby script/generate cucumber --webrat force config/database.yml create config/cucumber.yml create config/environments/cucumber.rb create script/cucumber create features/step_definitions create features/step_definitions/web_steps.rb create features/support create features/support/paths.rb create features/support/env.rb exists lib/tasks create lib/tasks/cucumber.rake
webratオプション無しだと警告が出ました。
webrat/capybara/rspec/testunit/sport が選択可能のようです。
(( : : )が点滅してます。どうやってんの?)
sudo rake RAILS_ENV=cucumber gems:install
何コレと思って、config/environments/cucumber.rb を覗くと
config.gem 'cucumber-rails', :lib => false, :version => '>=0.3.1' unless File.directory?(File.join(Rails.root, 'vendor/plugins/cucumber-rails')) config.gem 'database_cleaner', :lib => false, :version => '>=0.5.0' unless File.directory?(File.join(Rails.root, 'vendor/plugins/database_cleaner')) config.gem 'webrat', :lib => false, :version => '>=0.7.0' unless File.directory?(File.join(Rails.root, 'vendor/plugins/webrat'))
なるほどなるほど。
自動生成
$ ruby script/generate rspec_scaffold Article title:string content:text $ ruby script/generate feature Article title:string content:text $ ruby script/generate miso exists features/step_definitions create features/step_definitions/webrat_ja_steps.rb create features/step_definitions/web_extra_ja_steps.rb $ rake db:migrate $ rake cucumber ......... 2 scenarios (2 passed) 9 steps (9 passed) 0m0.370s
misoで生成されるファイルが日本語の素です。
cucumberの実行は、rake cucumberの他にもcucumberでも可。
features以下の構成はこんな感じ
今回いじったのは、下記コメントのファイル。
$ tree features/ features/ |-- manage_articles.feature # ここにテストシナリオを書きます。 |-- step_definitions | |-- article_steps.rb # シナリオ内での実際の動作を書きます。 | |-- web_extra_ja_steps.rb | |-- web_steps.rb | `-- webrat_ja_steps.rb `-- support |-- env.rb `-- paths.rb # ここにパス情報を書きます。
#features/manage_articles.feature Feature: Manage articles In order to [goal] [stakeholder] wants [behaviour] Scenario: Register new article Given I am on the new article page When I fill in "Title" with "title 1" And I fill in "Content" with "content 1" And I press "Create" Then I should see "title 1" And I should see "content 1" Scenario: Delete article Given the following articles: |title|content| |title 1|content 1| |title 2|content 2| |title 3|content 3| |title 4|content 4| When I delete the 3rd article Then I should see the following articles: |Title|Content| |title 1|content 1| |title 2|content 2| |title 4|content 4| #step_definitions/article_steps.rb Given /^the following articles:$/ do |articles| Article.create!(articles.hashes) end When /^I delete the (\d+)(?:st|nd|rd|th) article$/ do |pos| visit articles_path within("table tr:nth-child(#{pos.to_i+1})") do click_link "Destroy" end end Then /^I should see the following articles:$/ do |expected_articles_table| expected_articles_table.diff!(tableish('table tr', 'td,th')) end
日本語化
まずはFeatureから
Feature: Manage articles 管理者は、ブログの記事を管理できる
ここは何でもいいんですが、
元の英語のようにgoal/stakeholder/behaviorを意識した方がいいでしょう。
cucumberを再実行。問題ありません。
続いてScenario名
Scenario: 記事を登録する
ここも問題無し。
次はGiven。
Given I am on the new article page
仕組みはこんな感じ。
#step_definitions/web_steps.rb Given /^(?:|I )am on (.+)$/ do |page_name| visit path_to(page_name) end #support/paths.rb def path_to(page_name) case page_name when /the home\s?page/ '/' when /the new article page/ new_article_path
webrat_ja_steps.rbで
visit = lambda{|page_name| Given "I am on #{page_name}" } Given(/^"([^\"]*)"ページを表示している$/, &visit)
となっているので、こんな風に置き換えれます。
#support/paths.rb when /新規記事/ new_article_path #features/manage_articles.feature Given "新規記事"ページを表示している
他も同様にwebrat_ja_steps.rbとweb_steps.rbを見ると
日本語に置き換えれます。
こんな感じになりました。
#features/manage_articles.feature Feature: Manage articles 管理者は、ブログの記事を管理できる Scenario: 記事を登録する Given "新規記事"ページを表示している When "Title"に"title 1"と入力する And "Content"に"content 1"と入力する And "Create"ボタンをクリックする Then "title 1"と表示されていること And "content 1"と表示されていること Scenario: 記事を削除する Given 以下の記事を作成する: |title|content| |タイトル 1|コンテンツ 1| |タイトル 2|コンテンツ 2| |タイトル 3|コンテンツ 3| |タイトル 4|コンテンツ 4| When 3番目の記事を削除する Then 以下の記事を表示していること: |Title|Content| |タイトル 1|コンテンツ 1| |タイトル 2|コンテンツ 2| |タイトル 4|コンテンツ 4| #step_definitions/article_steps.rb Given /^以下の記事を作成する:$/ do |articles| Article.create!(articles.hashes) end When /^(\d+)番目の記事を削除する$/ do |pos| visit articles_path within("table tr:nth-child(#{pos.to_i+1})") do click_link "Destroy" end end Then /^以下の記事を表示していること:$/ do |expected_articles_table| expected_articles_table.diff!(tableish('table tr', 'td,th')) end
ほとんど日本語ですね。これでもテストが通ります。
最後に
テスト内に残っている英語(Title/Content/Createボタン/Destroy)を変更します。
ここは、scaffoldで生成される箇所です。
こうなりました。
#features/manage_articles.feature Feature: Manage articles 管理者は、ブログの記事を管理できる Scenario: 記事を登録する Given "新規記事"ページを表示している When "タイトル"に"タイトル 1"と入力する And "コンテンツ"に"コンテンツ 1"と入力する And "送信"ボタンをクリックする Then "タイトル 1"と表示されていること And "コンテンツ 1"と表示されていること Scenario: 記事を削除する Given 以下の記事を作成する: |title|content| |タイトル 1|コンテンツ 1| |タイトル 2|コンテンツ 2| |タイトル 3|コンテンツ 3| |タイトル 4|コンテンツ 4| When 3番目の記事を削除する Then 以下の記事を表示していること: |Title|Content| |タイトル 1|コンテンツ 1| |タイトル 2|コンテンツ 2| |タイトル 4|コンテンツ 4| #step_definitions/article_steps.rb Given /^以下の記事を作成する:$/ do |articles| Article.create!(articles.hashes) end When /^(\d+)番目の記事を削除する$/ do |pos| visit articles_path within("table tr:nth-child(#{pos.to_i+1})") do click_link "削除" end end Then /^以下の記事を表示していること:$/ do |expected_articles_table| expected_articles_table.diff!(tableish('table tr', 'td,th')) end
ここで再実行すると、「タイトル」って何って怒られます。
.F----... (::) failed steps (::) Could not find field: "タイトル" (Webrat::NotFoundError) (eval):2:in `fill_in' ./features/step_definitions/web_steps.rb:36:in `/^(?:|I )fill in "([^\"]*)" with "([^\"]*)"$/' features/manage_articles.feature:6:in `When "タイトル"に"タイトル 1"と入力する' Failing Scenarios: cucumber features/manage_articles.feature:4 # Scenario: 記事を登録する 2 scenarios (1 failed, 1 passed) 9 steps (1 failed, 4 skipped, 4 passed) 0m0.269s
テストが通るようにプロダクトコードを修正します。
(viewのラベルに日本語名を指定したり、ボタン名を日本語に変更)
そうすると、またテストが通るようになります。
......... 2 scenarios (2 passed) 9 steps (9 passed) 0m0.354s
あと
下記文言もそれぞれ日本語に変更可能ですが、
英語の方がしっくりきたのでそのままにしています。
Feature フィーチャ
Scenario シナリオ
Given 前提
When もし
And かつ
Then ならば