はじめに
FeatureSpecを勉強しようと色々調べているうちに、
SystemTestCaseなるものが存在する事を知り、SystemTestCaseやればいいじゃん!という事で、現在に至る。
Rails 5.1のSystemTestCaseを試してみた
を参考にさせて頂き、SystemTestCaseの勉強を始めていきます。
動作確認バージョン
- Ruby 2.5.3
- Rails 5.2.2
プロジェクト作成
プロジェクト作成
rails new system-test-sample
テスト用画面作成
scaffoldを用いて、テスト用の画面を作成します。
scaffold
rails g scaffold Person name:string birthday:string age:integer
rake db:migrate
この時点で既にテストケースのサンプルが出来ている。
./test/system/people_test.rb
require "application_system_test_case"
class PeopleTest < ApplicationSystemTestCase
setup do
@person = people(:one)
end
test "visiting the index" do
visit people_url
assert_selector "h1", text: "People"
end
test "creating a Person" do
visit people_url
click_on "New Person"
fill_in "Age", with: @person.age
fill_in "Birthday", with: @person.birthday
fill_in "Name", with: @person.name
click_on "Create Person"
assert_text "Person was successfully created"
click_on "Back"
end
test "updating a Person" do
visit people_url
click_on "Edit", match: :first
fill_in "Age", with: @person.age
fill_in "Birthday", with: @person.birthday
fill_in "Name", with: @person.name
click_on "Update Person"
assert_text "Person was successfully updated"
click_on "Back"
end
test "destroying a Person" do
visit people_url
page.accept_confirm do
click_on "Destroy", match: :first
end
assert_text "Person was successfully destroyed"
end
end
ChromeDriverのインストール
ChromeDriverのインストール
brew install chromedriver
テスト実施
テスト実施
$ rake
Run options: --seed 6623
# Running:
.......
Finished in 0.403665s, 17.3411 runs/s, 22.2957 assertions/s.
7 runs, 9 assertions, 0 failures, 0 errors, 0 skips
scaffoldした直後なので、もちろん問題なく通りますね。
※実際は、動いていなかった模様。(解決方法は後術)
テスト用のロジック追加
誕生日(birthday)と年齢(age)が正しいかのバリデーションを追加して、そのテストをする事にします。
./models/Person.rb
class Person < ApplicationRecord
validate :age_check
def age_check
date_format = "%Y%m%d"
now_age = (Date.today.strftime(date_format).to_i - birthday.to_i) / 10000
errors.add(:base, "誕生日か年齢が正しくありません。") if age != now_age
end
end
テストコード追加
./test/system/people_test.rb
test "age_check_ok" do
visit people_url
click_on "New Person"
fill_in "Age", with: 3
fill_in "Birthday", with: (Date.today.years_ago 3).strftime('%Y%m%d')
fill_in "Name", with: "Newburu"
click_on "Create Person"
assert_text "Person was successfully created"
end
test "age_check_ng" do
visit people_url
click_on "New Person"
fill_in "Age", with: 3
fill_in "Birthday", with: (Date.today.years_ago 2).strftime('%Y%m%d')
fill_in "Name", with: "Newburu"
click_on "Create Person"
assert_text "誕生日か年齢が正しくありません。"
end
テスト実施(これで上手く動きました)
テスト実施
$rails test:system
Run options: --seed 12406
# Running:
Capybara starting Puma...
* Version 3.12.0 , codename: Llamas in Pajamas
* Min threads: 0, max threads: 4
* Listening on tcp://127.0.0.1:56532
......
Finished in 5.004133s, 1.1990 runs/s, 1.1990 assertions/s.
6 runs, 6 assertions, 0 failures, 0 errors, 0 skips
起動時にChromeとChromeDriverの組み合わせでエラーが出る場合があります。
※私の環境では出ました。
その場合は、エラーメッセージに従い、バージョンアップしてください。
Chromeが起動し、自動でテストが行われているのが確認できると思います。
エラー失敗時のスクリーンショットを確認
テストケースをエラーになるように修正
./test/system/people_test.rb
test "age_check_ok" do
visit people_url
click_on "New Person"
fill_in "Age", with: 3
fill_in "Birthday", with: (Date.today.years_ago 4).strftime('%Y%m%d') ←修正
fill_in "Name", with: "Newburu"
click_on "Create Person"
assert_text "Person was successfully created"
end
テスト実施
$ rails test:system
Run options: --seed 62620
# Running:
Capybara starting Puma...
* Version 3.12.0 , codename: Llamas in Pajamas
* Min threads: 0, max threads: 4
* Listening on tcp://127.0.0.1:57068
..[Screenshot]: tmp/screenshots/failures_test_age_check_ok.png
F
Failure:
PeopleTest#test_age_check_ok [{project_root}/test/system/people_test.rb:57]:
expected to find text "Person was successfully created" in "New Person\n1 error prohibited this person from being saved:\n誕生日か年齢が正しくありません。\nName\nBirthday\nAge\nBack"
bin/rails test test/system/people_test.rb:48
...
Finished in 7.278474s, 0.8243 runs/s, 0.8243 assertions/s.
6 runs, 6 assertions, 1 failures, 0 errors, 0 skips
自動でスクリーンショットが取得されます。
tmp/screenshots/failures_test_age_check_ok.png
まとめ
エラー時のスクリーンショットなど、設定は自動で行われるため、テストコードだけ書けばOK!
テストコードの勉強だけに注力すれば良いので、今まで画面テストまでは…と避けている方には是非にオススメします!!(自戒w)