【RSpec】Capybaraについて
はじめに
Rails+RSpec+Capybraの環境で開発、テストを行っているので、Capybaraについて整理しておきます。
Capybaraとは?
Capybaraは、Webアプリケーションのインテグレーション・テストを補助する為のライブラリです。 Capybaraが提供する本質的な機能としては、DSLとDriverの2点のみです。
DSL(ドメイン固有言語)
特定の問題に特化したコンピュータ言語です。Capybaraはテスティングフレームワークを操作する命令を、それぞれのフレームワークに依存しない形で提供します。つまり、テスティングフレームワークであるCucumberやRSpec,Test::Unitなどを透過的に利用できます。
ドライバー
Webアプリケーションのインテグレーション・テストには、ブラウザもしくはそれに類するものが必要です。その為に、Seleniumのようにブラウザを操作するフレームワークや、WebKitのようなブラウザのレンダリングエンジンを直接使う方法があります。Capybaraは、それらをドライバとして扱うことが出来ます。
CapybaraのDSL
画面遷移
メソッド | 機能 |
---|---|
visit | GETページで遷移します |
click_link click_bottun click_on
リンクとクリック機能
メソッド | 機能 |
---|---|
click_link(' id ') | ID指定でリンクをクリック |
click_link( 'リンクテキスト' ) | リンクのテキスト名でクリック |
click_button('ボタン名') | ボタン名でクリック |
click_on( 'テキスト' ) | リンクかボタンどちらかをクリック |
click_on( ’value' ) | ボタンの値指定でクリック |
フォーム入力機能
メソッド | 機能 |
---|---|
visit | GETページで遷移します |
fill_in('ラベルの名前') | それぞれの入力フォームに値を入れる |
choose('ラジオボタン') | ラジオボタンを選択する |
check('チェックボタン') | チェックボタンを選択します |
uncheck('チェックボタン') | チェックボタンの洗濯を外す |
attach_file('image', '/path/to/image.jpg') | 画像を添付します |
select('Option', from: 'Select box') | セレクトボックスを選択する |
スコープ機能
スコープ機能を利用することで、特定のエレメント下のみ操作できます。
within("li#unique_name") do fill_in 'Name', :with => '五十嵐さん' end
マッチャ
expect(page).to have_content('この文字見つかる') #このページにあるかな? expect(current_path).to eq(root_path) #パス合ってる?
別タブに移動して操作する
# 最後に開いたタブに移動している
switch_to_window(windows.last)
参考資料
【Rails】seed_fuについて
はじめに
Railsでは、rails db:seed
というコマンドがあり、db/seed.rb
にシードデータを入れておけば、勝手にシードデータを作成してくれます。しかし、これは1度だけシードデータを作成する場合はよいのですが、シードデータを編集して再度実行すると、同じデータを何個も作成されてしまうという問題点があります。そこで、今回は便利にシードデータを生成してくれるseed-fu
というgemを使って、development
,test
,production
それぞれの環境ごとにシードデータを作成する方法を紹介します。
gemの導入とファイルの作成
- gemの導入
gem 'seed-fu'
$ bundle install
- dbディレクトリ配下に
fixtures
を作成
これで、準備完了です。
環境ごとにシードファイルを分ける
この場合は、fixturesディレクトリの中に、それぞれの環境名ディレクトリを作成し、そこにシードファイルを設置することで実現できます。
シードデータを入れる
あとは、db/fixtures
配下にモデル単位でシードファイルを作成していきます。例えばUserモデルとBoardモデルが合った場合、次のように書きます。
User.seed do |s| s.id = 1 s.name = 'テストユーザー' s.email = 'public@example.com' end
Board.seed do |s| s.id = 1 s.title = 'テストタイトル' s.body = 'テスト本文' s.user_id = 1 end
上記のファイルを作成したら、rails db:seed_fu
でDBにデータが投入されます。 がしかし、これだとエラー発生してしまいます。
Userのデータが入る前に、BoardがUserを参照しようとしてしまっているからです。
シードデータの順番を制御する
これは簡単でプレフィックスを付けてあげるだけで解決します。
users.rb → 01_users.rb boards.rb → 02_boards.rb
これだけで、Userからデータを作成してくれて、先ほどの処理が成功します。
【RSpec】モジュールの使用方法について
はじめに
Rspecモジュールの作成・使用方法について紹介します。
初期設定に加えて
rails_helper
# This file is copied to spec/ when you run 'rails generate rspec:install' require 'spec_helper' ENV['RAILS_ENV'] ||= 'test' Dir[Rails.root.join('spec', 'support', '**', '*.rb')].each { |f| require f } #コメントアウトをはずしましょう RSpec.configure do |config| config.include LoginSupport #ここでsupport配下のものを呼び込んでいます。 end
これで、spec/support/
配下のものが呼び出せます。
例えば、Loginモジュールを作成できたりします。
login_support.rb(ここの記載はcapybaraを使用しています。)
module LoginSupport def login(user) visit root_path fill_in 'user_name', with: user.name click_button '次へ' fill_in 'user_password', with: 'password' click_button 'ログイン' end end
これで、spec内でモジュールのメソッドが使用でき流ようになります。
【RSpec】Factory_botについて
はじめに
Factory_Botの使用方法について説明します。(gemはインストール済とする)
初期設定
rails_helper.rb
RSpec.configure do |config| config.include FactoryBot::Syntax::Methods end
テストデータの作成方法
Userモデルがある場合、
spec/factories/配下にテストしたい該当モデルのファイルを作成する。 Userモデルならusers.rbという形でファイルを作成する。
spec/factories/users.rb
FactoryBot.define do factory :user do name { "test" } email { "example@com" } end end
このように、ファクトリを作成できます。
テストデータの使用方法
spec/models/users_spec.rb
RSpec.describe User, type: :model do let(:user){ FactoryBot.create(:user) } #通常の書き方 DB登録される let(:user){ create :user} #省略記法 let(:user){ FactoryBot.build (:user)} #通常の書き方 DB登録されない let(:user){ build :user} #省略記法 let(:user){ build :user, name: "hogehoge"} #上書きすることも可能 end
traitの使用
traitを使用することによって、factoryのデータを柔軟に変更できます。例えば、管理者、編集者、記者と分けたい場合はこのように記述します。
users.rb
FactoryBot.define do factory :user do sequence(:name) { |n| "user-#{n}" } password { 'password' } password_confirmation { 'password' } role { :writer } trait :admin do sequence(:name) { |n| "admin-#{n}" } role { :admin } end trait :editor do sequence(:name) { |n| "editor-#{n}" } role { :editor } end trait :writer do sequence(:name) { |n| "writer-#{n}" } role { :writer } end end end
呼び出すときは、このようにします。
users_spec.rb
RSpec.describe User, type: :model do let(:user){ create :user, :writer} 基本データにwriterのnameとroleを上書きする let(:user){ create :user, :admin} 基本データにadminのnameとroleを上書きする
参考資料
【RSpec】初期設定について
はじめに
RailsでRSpecを導入するときに、初期設定を忘れがちなので備忘録として残しておきます。
gemの追加(rspec)
Gemfile
gem 'rspec-rails'
$ bundle install
これでgemを入れることができました。
設定ファイルを作成するコマンド
$ rails g rspec:install
コマンドを実行すると、下記のファイルが作成されます。
create .rspec create spec/spec_helper.rb #RSpecの全体的な設定を書く create spec/rails_helper.rb #Rails特有の設定を書く
.rspecの設定
# 出力結果を色分け --color # rails_helperの読み込み --require rails_helper # 出力結果をドキュメント風に見やすくする --format documentation
デフォルトだと--require spec_helperとなっているが、RailsでRSpecを使う場合は、--require rails_helperを使うのがベターです。
理由としては、後述するrails_helper.rbで既にrequire spec_helperを行なっているためです。
テストデータ生成用のgem(factory_bot)
Gemfile
$ gem 'factory_bot_rails'
$ bundle install
facotory_botのgemを入れることができました。
下記の設定により、FactoryBotのデータ呼び出しを簡略化できます。
spec/rails_helper
require 'spec_helper' ENV['RAILS_ENV'] ||= 'test' RSpec.configure do |config| # FactoryBotの省略 config.include FactoryBot::Syntax::Methods #ここです end
この設定をすると、
FactoryBot.create(:user)
→create(:user)
のように簡略化できます。
テストの補助ツール gem(capybara)
Gemfile
gem 'capybara'
$bundle install
spec/spec_helper
RSpec.configure do |config| require 'capybara/rspec' end
で使用できるようになります。
参考資料
【Rails】custom predicateについて(ransack)
はじめに
ransackのcustom predicateとは、name_eqやname_contのeqやcontなどのpredicate(述語)をカスタマイズして、自由に設定できるものです。
実装
まず、config/initializers下にransack.rbファイルを作成しましょう。
公式ドキュメントに下記の記載方法がのっています。
# config/initializers/ransack.rb Ransack.configure do |config| config.add_predicate 'equals_diddly', # Name your predicate # What non-compound ARel predicate will it use? (eq, matches, etc) arel_predicate: 'eq', # Format incoming values as you see fit. (Default: Don't do formatting) formatter: proc { |v| "#{v}-diddly" }, # Validate a value. An "invalid" value won't be used in a search. # Below is default. validator: proc { |v| v.present? }, # Should compounds be created? Will use the compound (any/all) version # of the arel_predicate to create a corresponding any/all version of # your predicate. (Default: true) compounds: true, # Force a specific column type for type-casting of supplied values. # (Default: use type from DB column) type: :string, # Use LOWER(column on database). # (Default: false) case_insensitive: true end
一つずつ解説していきます。
# こちらでブロックを作ります。 Ransack.configure do |config| #ここでpredicateの名前を決めています。これを実際のビューとかで使われるわけですね。 config.add_predicate 'equals_diddly' # どんな動きをするかを指定 arel_predicate: 'eq' # vが検索されて受け取る値になります。{ |v| "#{v}-diddly" }このブロック内で自分で自由にフォーマットを変えることができます。 formatter: proc { |v| "#{v}-diddly" } # こちらでバリデーションを決めています。 validator: proc { |v| v.present? } # これは恐らく複数のarel_predicateの組み合わせをtrueにするかということだと思います。デフォルトはtrueなので、特にあまりいじらなくて良いかと思います。 compounds: true # stringやintegerなどのタイプを指定します。 type: :string # 大文字、小文字の区別をする設定です。デフォルトはfalseです。 case_insensitive: true
このような記法で設定していきます。
例えば、
作成日の範囲指定では、掲示板の作成日に対して「◯◯月◯◯日〜◯◯月◯◯日」という検索をかけたいとき、
<%= f.date_field :created_at_gteq, class: 'form-control' %> 〜 <%= f.date_field :created_at_lteq, class: 'form-control' %>
これでは、1/1〜1/31日の午前0時まで間しか検索できません。
よって、lteqをカスタマイズします。
ransack.rb
Ransack.configure do |config| config.add_predicate 'lteq_end_of_day', # 述語の名前 arel_predicate: 'lteq', #lteqを使用 formatter: proc { |v| v.end_of_day } #上記のものをカスタマイズ end
これで
<%= f.date_field :created_at_gteq, class: 'form-control' %> 〜 <%= f.date_field :created_at_lteq_end_of_day, class: 'form-control' %>
と実装すれば、1/1から1/31日23時59分までの検索をすることができます。
【Rails】gem enum_helpについて
はじめに
前回、enumについて記事【Rails】enumについてをあげたのですが、それをi18n化する便利なgemがありましたの紹介します。その名も、enum_helpです。
enumをi18n対応させよう!!
まず、gemを入れます。
Gemfile
gem 'enum_help'
そして、
$ bundle install
localeファイルに追記
ja: enums: user: role: admin: 管理者 general: 一般
あとは、呼び出すだけです。
# 管理者user # adminに0を設定している user.role_i18n => '管理者' # 一般user # generalに1を設定している user.role_i18n => '一般'