自転車とプログラミング

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

「Everyday Rails - RSpecによるRailsテスト入門」でRSpecを学ぶ 序章

こんにちは、watanabeです。 今回はRailsの自動テストの定番「RSpec」を学んでいきます。

私に関してはこれまでRails標準の「minitest」を自動テストツールとして使用してきました。

ポートフォリオを作るときも、RSpecRailsデファクトスタンダードとは知っていましたが、 学習コストを勘案してminitestを使うことにしていました。

Railsを採用している企業ではRSpecを使っていることがほとんどなので学ばない道はないかなーという感じで学習することに決めました。

教材

RSpecの教材としては定番?の「Everyday Rails - RSpecによるRailsテスト入門」を使います。 フィヨルドブートキャンプのメンター兼ソニックガーデンのエンジニアをされている伊藤淳一さんが訳をされています。

伊藤さんといえば発信した情報の面倒見が非常に良い人だと感じています。 Qiitaで数多くの記事を出されていますが時間経過に伴って適宜修正を加えられているのをよく目にします。 こちらの参考書もRails7に対応修正した初心者〜中級者向けの内容となっているので信頼度が高いかなと思います。

leanpub.com

minitetstと比べて

RSpecは学習教材が豊富なのが良いですよね。 minitestとRSpecを比較したときにminitestのほうが軽量で速いとか、RSpecのほうが自然言語的にテストを記述できてわかりやすいとかメリデメが出てきますが、 ある程度使える様になるには学習が必要なわけですが、RSpecのほうがそのへんの情報が豊富だなーと思います。 今回の参考書は250ページくらいのボリュームでサクッと読めます。

ポートフォリオでminitestを使っている際はハマった際に解決の糸口が出てこず、けっこう悩まされました。 ヒットしてもRSpecの情報だった、ということはざらにありました。

そこら辺を鑑みると「学習コスト」を避けてminitestを選んだものの、最初からRSpecを使っていればある程度のレベルまで教材で学んで、外部情報にもあたれるので楽だったのかもしれませんね。

RSpecのメリット

BDDスタイル

RSpecはBehavior-Driven Development(BDD/ふるまい駆動開発)を強くサポートしており、自然言語に近い記述が可能です。

BDDとはソフトウェアの動作やふるまいに焦点をあてて、ユーザーや他のシステムとの相互作用の観点からテストケースを定義します。 たとえば「ユーザーモデルに関して、ログインするとき、秘匿情報が検証できたら、ダッシュボードページにリダイレクトする」というふるまいは↓のようになります。

# spec/user_spec.rb
RSpec.describe User do #ユーザーについて
  describe "#login" do # ログインするとき
    context "with valid credentials" do #秘匿情報が検証できたら
      it "redirects to the dashboard" do # ダッシュボードページにリダイレクトする
        user = User.new(valid_credentials)
        result = user.login
        expect(result).to redirect_to(dashboard_path) 
      end
    end
  end
end

最終的には expectで予期した結果と実際の結果が合致すればテストが通ります。 minitestではここまで精密にシナリオやふるまいを記述できず、メソッド名にテスト概要を書けるにとどまります。そのため、あとはテストコードを確認して詳細を知る必要があります。

テストコードがドキュメントとしても機能します。

豊富なDSL:

"describe", "context", "it" などのドメイン固有言語(DSL)を使って、テストを記述します。 minitestはあくまでRubyの仕様において構造が組み立てられますが、RSpecは独自の構造を組み立てられる様になっておりBDDを容易にしています。

その他

ざっと参考書を読んだ感じですが、モックやスタブを簡単につかったり、カスタムマッチャを作れたりと拡張性の高さが魅力的だと思いました。 読みやすいテストを書いて、TDDしていく。しかもテストが仕様書として機能してくれるので作る側からすると助かるだろうなーという印象です。

おわり

次回から実際にテストを書いていこうと思います。