Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Capybaraで変更に強いE2Eテストを書く / TokyuRubyKaigi12

Capybaraで変更に強いE2Eテストを書く / TokyuRubyKaigi12

TokyuRuby会議12(2018/07/29)

Yuichi Goto

July 29, 2018
Tweet

More Decks by Yuichi Goto

Other Decks in Programming

Transcript

  1. 対応するCapybaraのコード例 • タグ名で指定: all("table > tr")[1] • 既存のクラス名で指定: find(".for-styling") •

    画面内の文言で指定: click_button("จݴ") !6 _人人人人人人人_ > 見たことある  <  ̄Y^Y^Y^Y^Y^Y^Y ̄
  2. お題: ログインフォーム <h2>Sign in</h2> <%= form_with model: resource, url: session_path(resource_name)

    do |f| %> <%= field_set_tag nil, class: "form-group" do %> <%= f.email_field :email, placeholder: "Email", class: "form-control form-control-lg", "data-testid": "email" %> <% end %> <%= field_set_tag nil, class: "form-group" do %> <%= f.password_field :password, placeholder: "Password", class: "form-control form-control-lg", "data-testid": "password" %> <% end %> <%= f.submit "Sign in", class: "btn btn-lg btn-primary", "data-testid": "submit" %> <% end %> <%= render "users/shared/links" %> !11 テストで使う要素にdata属性を振っておく
  3. data属性を使って書くE2Eテストの例 require "rails_helper" RSpec.describe "User sign in", type: :system do

    let(:user) { FactoryBot.create(:user) } before do visit new_user_session_path end it "should allow users to sign in with their email and password" do find("[data-testid='email']").set(user.email) find("[data-testid='password']").set(user.password) find("[data-testid='submit']").click expect(page).to have_current_path(root_path) end end !12 タグ名、クラス名、画面内の文言に 依存していないのがポイント
  4. Ruby on Rails向けにも作れないか? • Haml/Slim向けにならほぼ同じ方法で作れるが・・・ • テンプレートエンジンごとにgem作ることになる • 素のHTML +

    ERBで書いている人は使えない !16 Railsのヘルパー呼び出しに介入する方法なら
 制約はあるものの汎用的なものが作れるのでは?
  5. data-testid を取り除く例 <form action="/users/sign_in" accept-charset="UTF-8" data-remote="true" method="post"> # (snip) <input

    type="submit" name="commit" value="Sign in" class="btn btn-lg btn-primary" data-disable-with="Sign in" /> </form> !18 <%= form_with model: resource, url: session_path(resource_name) do |f| %> # (snip) <%= f.submit "Sign in", class: "btn btn-lg btn-primary", "data-testid": "submit" %> <% end %> オプションとして渡したものが 取り除かれる
  6. 仕組み • Railsの link_to などのViewヘルパーは内部的ʹ tag_options というメソッドを呼び出している • このメソッドに渡されたオプションを書き換える !19

    # remove_data_attributes/lib/remove_data_attributes/ tag_options_filter.rb define_method(method_name) do |options, escape = true| options.is_a?(::Hash) ? super(processor.call(options), escape) : super(options, escape) end