koheitakahashiのブログ

2020.07.01にプログラマーとして生を受けた私が学んだことや、日常について徒然に書いていきます。

『Everyday Rails - RSpec による Rails テスト入門』を読了しました

はじめに

実は、私はRSpecをしっかりと学んだことがなく、今までminitestでテストを書き続けておりました。

現在、自分のアプリの開発でRSpecを採用しては見たものの、行き当たりばったりで全体像が掴めていないと感じました。

そのため、RSpecを体系的に学びたいと思い、『Everyday Rails - RSpec による Rails テスト入門 -テスト駆動開発の習得に向けた実践的アプローチ-』を読みました。

本書を読んで、学んだこと、感想をまとめたいと思います。

leanpub.com

本書の章立て

第1章 イントロダクション

第2章 RSpecのセットアップ

第3章 モデルスペック

第4章 意味のあるテストデータの作成

第5章 コントローラースペック

第6章 フィーチャースペックでUIをテストする

第7章 リクエストスペックでAPIをテストする

第8章 スペックをDRYに保つ

第9章 速くテストを書き、速いテストを書く

第10章 その他のテスト

第11章 テスト駆動開発に向けて

第12章 最後のアドバイス

付録A システムスペックに移行する

章ごとの感想

第2章 RSpecのセットアップ

章のタイトルの通り、プロジェクトにRSpecを導入するとき方法や設定がまとめられた章でした。

ここで、初めて知ったのですが、以下を記述すると、RSpec.rspecファイルに--format documentationと記述することで、出力を読みやすい形式にすることができるようです。

実際に自分の既存のプロジェクトで出力の違いを見てみると、以下のようになりました。

❯ be rspec             
.....

Finished in 3.54 seconds (files took 4.25 seconds to load)
5 examples, 0 failures

--format documentationを記述したとき

❯ be rspec

AppelMusicRepositoryのmodelテスト
  APIレスポンス(mock)を取得する
    #search

SpotifyRepositoryのmodelテスト
  APIレスポンス(mock)を取得する
    #search

YoutubeRepositoryのmodelテスト
  APIレスポンス(mock)を取得する
    #search

楽曲検索機能
  検索フォームに入力した楽曲をSpotify APIを介して検索
    検索結果を表示する
    SpotifyとYoutube、Apple MusicのURLを表示する

Finished in 3.14 seconds (files took 3.31 seconds to load)
5 examples, 0 failures

これは、確かに読みやすいので、早速記述を追加したいと思いました。

第3章 モデルスペック

モデルスペック、いわゆるモデルの単体テストについてまとめられた章です。

モデルスペックに含めるべきテスト内容や、具体的なベストプラクティスが示されていて、とても参考になりました。

特に、describecontextitの書き方がまだしっくりきていない私にとっては、その使い方や意味が明文化されたことで、書き方の方針が少し掴めたような気がしています。

本書を読んで理解したところをざっくり書いてみると・・・

  • describeにはクラスやシステムの機能のざっくりとした内容を説明文に書きます。
  • contextは場合分けをする時に使い、特定の状態に関する説明文を書きます。
  • itは期待する結果一つだけを書きます。ここの説明文は動詞で始まると分かりやすいものになります。

という感じなるでしょうか。なんとなく使い方が掴めたので、私にとってはとてもありがたい内容でした。

第4章 意味のあるテストデータの作成

FactoryBotを使ったテスデータの作成についてまとめられている章です。

私はFixturesしか触れてこなかったため、FactoryBotが簡単に関連づけされたモデルのテストデータを用意することができるというところにFactoryBotの利点を感じました。

また、作成したFactoryを継承することができるという点もFixturesとは異なっていて、「助かる場面が多そうだなー」と思いました。

第5章 コントローラースペック

コントローラーのテストに関する章でした。

そもそも、コントローラーの役割はパラメーターを受け取って、他のところに渡しているというものなので、そもそも複雑なことはやっておらず、テストも複雑なことをしなくて良いという感じでした。

ただ、実際にコントローラースペックもコントローラー同様に肥大化しやすいそうなので、テストであっても誰の責務なのかということを意識し、積極的に切り分けをしていかなければならないと思いました。

第6章 フィーチャースペックでUIをテストする

フィーチャースペックで、UIを通してモデル・コントローラーの協調をテストする方法についてまとめられています。

ただ、RSpecではシステムスペックが使えたなーと思い出し、システムスペックとフィーチャースペックとどう違うのかというところに疑問を持ちました。

そこで、実際にFJORD BOOT CAMPでjnchitoさんにお聞きしたところ、基本的には書き方などはほとんど同じで、これから学んだり、使っていくのであればシステムスペックで良いそうです。

元々、フィーチャースペックはminitestにシステムテストが実装される以前からあったRSpec独自のインテグレーションテストだったようです。

しかし、minitestにシステムテストが実装されたため、RSpecもそれに倣った形で実装されたという経緯があるようです。

以上のようなことをjnchitoさんからお聞きしたのですが、実はそれに関連することが本書の「付録A」に記載されているという。。。

第7章 リクエストスペックでAPIをテストする

APIをどのようにテストするかということがまとめられている章でした。

そもそも、コントローラーテストでAPIのテストもできるのではという話もありますが、もっとシンプルにHTTPリクエストを使ってテストすることができるのが、リクエストスペックということで私は理解しました。

第8章 スペックをDRYに保つ

スペックをDRYにするための、テクニックがまとめられた章です。

ここで印象的だったのは、RSpecでは自分でマッチャを作成できるということです。

ただ自分はデフォルトのものがあればそれを使ってなんとかしたいと考えてしまうので、あまり使う機会はなさそうだなーとは思うのですが、実際に多く使われるものなのでしょうか🤔

また、ある部分でテストが落ちてもテストを続けることができるaggregate_failuresも印象的でした。 ただ、一度、aggregate_failuresを使ってしまうと、全てのテストに使ってしまいたくなりそうなので、使い所の見極めと、しっかりとした理由づけが必要そうです。

第9章 速くテストを書き、速いテストを書く

実行時間が短く、綺麗なスペックをいかに書いていくためのgemやテクニックがまとめられた章でした。

この章で印象に残ったのは、モックとスタブのお話です。 自分はWebMockを使ったことはあるのですが、モックとスタブの定義が毎度ごっちゃになってしまっていて、ここでは以下のように明文化されていて、とても分かりやすかったです。

  • モックとは、本物のオブジェクトのふりをするオブジェクト。
  • スタブはオブジェクトのメソッドをオーバーライドして決められた値を返すようにすること。

そして、モック化に関しては

「自分で管理していないコードをモック化するな」

という言葉が、モックの使い方に関する指針を示してくれていて良かったです。

第10章 その他のテスト

上記以外の、ファイルアップロードや外部APIに対するテストの方法などがまとめられている章でした。

外部APIに関するテストのところで、VCRというgemがあることをしりました。

これは、リクエストとレスポンスをファイルに記録しておいて、記録されたリクエストが送られた時は、記録されたレスポンスを返すということをやってくれるようです。

上述するようにWebmockを使ったことがあったのですが、こちらは初めて知りました。

ただ、適切な使い方をしないと記録しているファイルにどんどんと色んなリクエストとレスポンスが溜まっていくような気がして、使うならばしっかり使わなければいけないのかなと想像しました(色々設定などはあるでしょうが・・・。

第11章 テスト駆動開発に向けて

テスト駆動開発を実際にテストコードを書きながら進めていくという章でした。

新鮮だったのは「外から中へ」テストを実装していくということでした。最初にフィーチャースペックを書いて、その中でテストが必要だと感じた内容にについてはコントローラースペックとして実装、そして、モデルスペックを実装という内容です。

私は、ユニットテスト→統合テスト→UIテストという順番でテストは書いていくものだと思っていました。この考え方は、Jonathan Rasmusson著 『初めての自動テスト Webシステムのための自動テスト基礎』で述べられていたと思います。

しかし、本書の「外から中へ」の考え方は、上記の考え方とは真逆のものだと思われます。

イマイチ、私の中で両者の考え方の利点を把握できていないので、実際に両者を試してみて、その利点を実感できればと思いました。

第12章 最後のアドバイス

テストを書くときの心構えがまとめられた章でした。

自分はモデルテストは実装したメソッド全てに対応するテストを書こうと意識しているのですが、システムテストのレベルになるとどこまでテストして良いものか・・・と悩むことが往々にしてあります。

そのため、この章で述べられている「自分の取り組んでいるものが実装できるようにスペックを追加する」という観点でテストを考えてみると、少し考えやすくなるのかなーと思いました。

全体を通しての感想

これまで、行き当たりばったりでRSpecのテストを書いていきたのですが、本書を読んで今までなんとなく使っていた構文を使うための指針が明文化されており、とても有り難かったです。

ただ、やはり、分かりやすいテストを早く書くということは一朝一夕でできるものではないと感じました。そのため、本書を指針として、テストを書いていくことで、テストの経験値を高められればと思いました。