【現場で使える Ruby on Rails 5速習実践ガイド】の感想・気づき(5章)

-2018.12.18 -書籍
-, ,

スポンサーリンク

現場で使える Ruby on Rails 5速習実践ガイドとは?

10月に発売されたRailsの技術書で、
Ruby・Railsの開発支援をされている株式会社万葉の方々が監修している書籍です。

通称現場Railsと呼ばれています。

2018年12月現在の最新のRails技術書ということもあり、Rails5.2に対応しています。

読書対象者としては他言語でのWEBアプリケーション開発や、オブジェクト指向プログラミングについての知識・経験がある方と明記されていたので全くの初学者向けではない書籍にはなっています。

5章 RSpecを用いたテストが終わったので内容を振り返ってまとめてみました。

テストを書くメリット

RPA(Robotic Process Automation)というノンプログラミング・GUIの業務自動化ツールが数年前からビジネスシーンで盛り上がりを見せていますが、開発の現場ではRSpecしかりプログラムでアプリケーションの操作を自動テストするテスティングフレームワークが数多く用いられています。

(厳密には、テスティングフレームワークはブラウザ操作を主な対象とするのに対して、RPAはローカル環境にインストールして用いるアプリケーションも含めた横断的なテストが行なえます。)

本書で述べられていたテストのメリットは以下の通りです。

  • テスト全体にかかるコストの削減
  • 変更をフットワーク軽く行えるようになる
  • 環境のバージョンアップやリファクタリングの必須条件
  • 仕様変更の影響を簡単に把握できる
  • 仕様を記述したドキュメントとしても機能する
    • RSpecは動く仕様としての面にフォーカスして作られた
  • 仕様やインターフェイスを深く考えるきっかけにもなる
  • 適切な粒度のコードになりやすい
  • 開発工数が上がる

確かに、ある機能をリリースする度に各ブラウザで動作確認するだけよりも、まずテストを流して影響範囲を確認することには様々な利点があるはず。中でも、より良い仕様を考えるきっかけになる・適切な粒度のコードになるといったことはあまり意識していなかったので今後は取り入れたいと思います。

テスト用ライブラリ

RSpec

  • RubyのBDD(振舞駆動開発)テスティングフレームワーク
  • 動く仕様書(Spec)として自動テストを書くという思想
  • Minitestより多機能で複雑だが開発現場で広く利用されている

Capybara

  • E2Eテスト用フレームワーク
  • ブラウザ操作をDSLでシミュレーションできる
  • Seleniumのようなドライバと組み合わせてJSの動作を含めたブラウザ操作のテストが出来る

FactoryBot

  • テスト用データの作成をサポートする
  • Rails標準同梱のFixtureの代替
  • FixtureはYAML形式、シンプルだが複雑な処理が苦手
  • FactoryBotはDSLを用いることで複雑な処理も行いやすい

の3つを用いたテストの手法が本章では取り上げられました。

特にRSpec gem ver 3.7以降ではSystem Specというシステム全体のテストが追加されました。
System Specには

  • テスト終了時にデータベースがロールバックされる
  • テスト終了時にスクショが生成される
  • driven_byを用いてブラウザを簡単に切り替えられる

というメリットもあり、現場で採択されるケースが多いのだと思いました。
Minitestしか触ったことがない者からすると、スクショが自動生成されるのは感動モノでした!

インスタンス変数の代わり? let

RSpec自体初めて触れたのですが一番理解しにくかったのがこの let

let (定義名) { 定義内容 }

の形で用い、以下のような特徴を持ちます。

  • letを定義した外側でも内側でも定義名を呼び出せる
  • letのブロックが実行されるタイミングはletが初めて呼ばれたとき(遅延評価と呼ぶ)
  • 定義した位置で呼びたい場合は let! を用いる
describe 'タスク管理機能', type: :system do
  describe '一覧表示機能' do
    let(:user_a) { FactoryBot.create(:user, name: 'ユーザーA', email: 'a@example.com') }

    before do
      FactoryBot.create(:task, name: '最初のタスク', user: user_a)
      visit login_path
      fill_in 'メールアドレス', with: login_user.email
      fill_in 'パスワード', with: login_user.password
      click_button 'ログインする'
    end

    context 'ユーザーAがログインしているとき' do
      let(:login_user) { user_a }

      it 'ユーザーAが作成したタスクが表示される' do
        expect(page).to have_content '最初のタスク'
      end
    end
  end
end

であれば、

  • 6行目の user_a が読み込まれたとき、3行目の let が呼ばれる
  • 8行目の login_user が読み込まれたとき、14行目の let が呼ばれる

ということが内部的に起きているそうで、

この遅延評価という概念やスコープの定義がローカル変数とは異なるので苦戦しそうな印象は持ちました。

他にも色々なテスト記法が出てきたので、Everyday Rails – RSpecによるRailsテスト入門も手に取りながらテストについてはじっくり学んでいこうと思います。

t_wadaさんのテスト駆動開発も積ん読してしまっているのでもう一度読んでみようかな。

この記事の内容が役に立ったと思いました、SNSで記事を共有していただけますと幸いです。