こんにちは、watanabeです。
引き続きRSpecの学習内容をまとめていきます。
システムスペック
システムテストとほぼ同義の高レベルテスト。
テストレベルの高低は低レベルは単体テストのような実装のより詳細を、高レベルはシステム全体の動作やUXをテストする。
類語
E2Eテスト、システムテスト、統合テストはシステムスペックの類語
システムスペックの前身としてフィーチャスペックがある。
記法
システムテストで使用しているブラウザシミュレーターのCapybaraをシステムスペックでも使用するのでマッチャ以外の部分は大体共通に書ける。
scenario "user creates a new project" do user = FactoryBot.create(:user) visit root_path click_link "Sign in" fill_in "Email", with: user.email fill_in "Password", with: user.password click_button "Log in" visit root_path expect { click_link "New Project" fill_in "Name", with: "Test Project" fill_in "Description", with: "Trying out Capybara" click_button "Create Project" aggregate_failures do expect(page).to have_content "Project was successfully created" expect(page).to have_content "Test Project" expect(page).to have_content "Owner: #{user.name}" end }.to change(user.projects, :count).by(1) end
ユーザーとしてログインしてプロジェクトを作成するフローのテスト。 scenario … do ~ end
がシナリオスペックの構文ですが、it構文にも置き換えられます。
user = FactoryBot.create(:user) visit root_path click_link "Sign in" fill_in "Email", with: user.email fill_in "Password", with: user.password click_button "Log in" visit root_path
ユーザーを作って visit ...path
からブラウザをシミュレート。該当パスへ移動して、 click_link 要素名
でページ内の要素をクリック、 fill_in ... with: 入力内容
で該当箇所への入力、 click_button "Log in"
でログインを実行。
expect { click_link "New Project" fill_in "Name", with: "Test Project" fill_in "Description", with: "Trying out Capybara" click_button "Create Project" aggregate_failures do expect(page).to have_content "Project was successfully created" expect(page).to have_content "Test Project" expect(page).to have_content "Owner: #{user.name}" end }.to change(user.projects, :count).by(1)
この部分ではexpectをネストさせてページの表示内容がただしいかどうか、をテストしてから、挙動の結果としてUser.projectsが増えているかどうかをテスト。
ページ内容のチェックは普通に必要なことに加えて、Capybaraの仕様的にブラウザシミュレートよりもテスト処理が早く進むことがあるため場合によってはexpectを挟むのがベターというテクニックがあります。
システムスペックのライブラリ
システムスペックで使用するライブラリとしてはRSpecそのものとは別にCapybaraとSelenium-webdriverがあります。
Capybaraはブラウザの動作をシミュレートします。 click_button
などのDSLが用意されています。
Selenium-webdriverはもともとはブラウザを遠隔操作するWebdriverですが、今回に関してはCapybaraでは対応できないJavaScriptの動作を実行させるために必要になります。
動作としてはCapybara単体でも動作する rack_test
のほうが速いため、使い分けを設定するとテストがより早く完了するようになる。
RSpec.configure do |config| config.before(:each, type: :system) do driven_by :rack_test end config.before(:each, type: :system, js: true) do driven_by :selenium_chrome end end
ここではJavaScriptの処理が必要になったときだけSeleniumでChromedriverを使用し、それ以外はRackを使用することになる。minitestで同様の設定をしたことがありますが、たしかに速くなった記憶があります。
教材はこちら
RSpec初心者の教材としては定番?の「Everyday Rails - RSpecによるRailsテスト入門」を使っています。 フィヨルドブートキャンプのメンター兼ソニックガーデンのエンジニアをされている伊藤淳一さんが訳をされています。 Rails7に対応修正した初心者〜中級者向けの内容となっているので信頼度が高いかなと思います。