自転車とプログラミング

元自転車メーカーのマーケター、今は自社開発企業に勤めるエンジニアが主にプログラミングの話を書きます。

「Everyday Rails - RSpecによるRailsテスト入門」でRSpecを学ぶ 導入〜システムスペック編

こんにちは、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に対応修正した初心者〜中級者向けの内容となっているので信頼度が高いかなと思います。

leanpub.com