MAGAZINE
ルーターマガジン
Rails ToDoアプリでアカウント登録とDBのCRUD操作をRSpecとheadless chromeでテストする(WSL環境)
こんにちは。アルバイトのハオと申します。初めての記事で、よろしくお願いいたします。
Ruby on Rails (略称Rails) は、Webアプリのフレームワークであります。
今はRailsを使って会社の内部向け運用管理画面を構築しています。最近この管理画面に対してテストをしまして、テスト作成の経験をシェアしたいと思います。
今回の記事は、こちらを参考にして作成した、タスク管理アプリ(todoアプリ)に対するテストをテーマにします。
少しこのアプリを紹介します。このアプリはユーザー新規登録、ログイン、そしてユーザーのタスクの新規追加、更新、削除ができます。これからアプリの画面を見せます。
まずはユーザー新規登録、ユーザーログインの画面です。
タスク一覧画面です。ログインしているユーザーのタスクを全部表します。上にタスク新規追加のボタンがあり、タスク行の右に編集と削除ボタンもあります。
タスク新規追加の画面です。タイトル、ノート、タスク完成の時間を入力できます。
タスク編集の画面です。タイトル、ノート、タスク完成の時間を更新できます。
では、テストの作成に入りましょう。
chromedriverをダウンロード
テストのため、chromedriverでgoogle chromeを起動する必要があります。
持っているgoogle chromeのバージョンと合致したchromedriverをダウンロード。
WSLの方はwindows環境にダウンロードし、chromedriver.exe
をCドライブに移します。
例えば、僕はC:\Program Files\chromedriver_win32\
に移しました。
あとでchromedriverへのパスを指定します。
必要なgemをインストール
Gemfile
のtest グループを以下の通りに編集
group :test do gem 'capybara', '>= 2.18' gem 'rspec-rails', '>= 3.7' #追加 gem 'selenium-webdriver' gem 'capybara-email' #追加 gem 'email_spec' #追加 # 下の行を削除してください # gem 'chromedriver-helper' end
今回はheadless chromeを使うため、chromedriver-helperはいりません。ちなみにchromedriver-helperはサポートがもう終了したようです(https://github.com/flavorjones/chromedriver-helper)
追加したgemをインストール
$ bundle install
テスト環境の設定
$ bundle exec rails g rspec:install
を実行することで、spec/rails_helper.rb
とspec/spec_helper.rb
が新規作成されます。
まずspec/spec_helper.rb
を編集しましょう。ファイルに、ダウンロードしたchromedriverのパスを指定:
require 'selenium-webdriver' Selenium::WebDriver::Chrome.driver_path = "/mnt/c/Program Files/chromedriver_win32/chromedriver.exe"
同じファイルの下にあるRSpec.configure
の設定で、config.formatter = :documentation
を追加することをおすすめです。これによってテストするときに、scenarioごとにタイトルが出力されます。
RSpec.configure do |config| config.expect_with :rspec do |expectations| expectations.include_chain_clauses_in_custom_matcher_descriptions = true end config.mock_with :rspec do |mocks| mocks.verify_partial_doubles = true end config.shared_context_metadata_behavior = :apply_to_host_groups # Print the name of each scenario config.formatter = :documentation #追加 end
次はspec/rails_helper.rb
です。capybara/rails
とcapybara/email/rspec'
をインポート:
require 'capybara/rails' require 'capybara/email/rspec'
続いてheadless chromeに関する設定を追加:
Capybara.default_driver = :selenium_chrome_headless Capybara.register_driver :selenium_chrome_headless do |app| options = Selenium::WebDriver::Chrome::Options.new options.add_argument('headless') options.add_argument('--disable-gpu') Capybara::Selenium::Driver.new(app, browser: :chrome, options: options) end
続いて下のActiveRecordに関する設定を削除してください:
begin ActiveRecord::Migration.maintain_test_schema! rescue ActiveRecord::PendingMigrationError => e puts e.to_s.strip exit 1 end
これを無効にしないと、テスト時に自動的にDBにmigrationがかかってしまいます。既にDBにテーブルが存在していてmigrationを使わない方にとっては、DBの内容を消去されてしまう恐れがあります。
続いて同じファイルの下にあるRSpec.configure
の方を編集します。
RSpec.configure do |config| config.include Capybara::DSL #追加 config.fixture_path = "#{::Rails.root}/spec/fixtures" # 次の行を削除またはコメントアウト又はfalseにしてください # config.use_transactional_fixtures = true config.infer_spec_type_from_file_location! config.filter_rails_from_backtrace! end
メールに関する設定
今回テスト対象としたToDoアプリの場合、テストアカウントを新規登録する際に確認メールが送信されますので、それについても設定しなければなりません。
config/environments/test.rb
を編集しましょう。
まず以下の行があるかどうか確認:
config.action_mailer.delivery_method = :test
この設定で、実在するメールアドレスへの送信は行われなくなります。
そしてホストを追加:
config.action_mailer.raise_delivery_errors = true config.action_mailer.default_url_options = { :host => 'localhost', :port => '3000' }
テストファイルの作成
以下のコマンドを実行してテストファイルを作成してください。
$ mkdir spec/features/ $ vim spec/features/todo_spec.rb
このサイトを参考してテストを書きましょう。
spec/features/todo_spec.rb
の中身:
require "rails_helper" feature "Todoアプリ、アカウントとタスクのテスト" do given(:email) { 'example@rooter.co.jp' } given(:password) { '000000' } scenario "アカウントを新規登録テスト" do visit "/users/sign_up" #新規登録画面へ fill_in "user_email", with: email fill_in "user_password", with: password fill_in "user_password_confirmation", with: password click_button "Sign up" sleep 3 open_email(email) #確認メールを開く current_email.click_link 'Confirm my account' #アカウント確認リンクを押す new_user = User.find_for_authentication(email: email) expect(new_user).to be_confirmed #アカウントが確認されたかどうか end feature "登録したアカウントでテスト" do background do visit root_path #ホームページにアクセスし、まだログインしていないのでログイン画面に自動遷移 fill_in "user_email", with: email fill_in "user_password", with: password click_button "Sign in" end scenario "タスク新規" do click_on "New task" #タスク新規の画面を開く fill_in "task_title", with: "test new task" click_on "Save" expect(page).to have_selector('td string', text: "test new task") end scenario "タスク編集" do find("i.icon-edit").click #タスク編集の画面を開く fill_in "task_title", with: "test edit task" click_on "Save" expect(page).to have_selector('td string', text: "test edit task").and have_no_selector('td string', text: "test new task") end scenario "タスク削除" do page.accept_alert do # 警告が出てくるアクションをこの中に包む find("i.icon-remove").click end expect(page).to have_no_selector('td string', text: "test edit task").and have_no_selector('td string', text: "test new task") end scenario "アカウントを削除テスト" do visit "/users/edit" #アカウント編集画面へ page.accept_alert 'Are you sure?' do # 'Are you sure?'警告が出てくるアクションをこの中に包む click_link "Cancel my account" end sleep 3 user = User.find_by(email: email) expect(user).to eq nil end end end
テストを実行しましょう!
$ bundle exec rspec spec/features/todo_spec.rb
緑文字ばかりで、赤い文字がなければ成功です。
参考資料
CONTACT
お問い合わせ・ご依頼はこちらから