メンテナブルにRailsのテストを書くならおさえておきたい8つのポイント

メンテナブルなRailsのテストを書くために必要なポイントについて説明したA Guide for Writing Maintainable Rails Testsという記事を見つけたのでご紹介します。

1. ユーザーに近いところからテストを書き始めよう

ユーザーに近いところ(受け入れテスト)からテストを書き始めることで、少しテストコードを書くだけで振る舞いの大部分をカバーすることができます。受け入れテストを書いてから、カバレッジの穴を埋めるような細かいテストを書くのが良いでしょう。

2. テストをDRYにするためにヘルパーメソッドを使おう

例えばユーザーログインなど、決まりきった処理はヘルパーメソッドにするとテストの見通しが良くなります。

3. コピペするな!

例えばRSpecのbefore内の前処理コードなんかは、重複することが多いですよね。でもそういった場合にコピペをすることなく、「ヘルパーメソッドにするべきか?」と自問するのが良いでしょう。

4. 既にテストされているものをテストするな!

例えばActiveRecordhas_manyや、validateなどをテストする必要があるでしょうか? 既にRails内で十分にテストされているはずなので、あえて自分たちのプロジェクト内で再度テストする必要はないはずです。既にテストされているものをテストする必要はありません。

5. モックとスタブを過度に使い過ぎないように

あまりにもモックやスタブを多用しすぎると、テストした結果と実際の振る舞いが乖離してしまう恐れがあります。テストが遅くなってしまうかも知れませんが、できるだけ実際のデータを使用するようにすれば、実際の振る舞いとテストが乖離するようなことはなくなるでしょう。

6. テストは高速に実行されるように書こう

とはいえ、本当に重要なことは信頼性が高く、理解しやすいコードを書くことです。

7. describeとcontextはあまりネストしないようにしよう

深くネストされすぎると、どういったステップでテストが実行されているのか見失いやすくなってしまいます。深いネストが発生した場合は、別々のテストにするか、もしくは別々のファイルにすることでネストしないようにすることを検討しましょう。

8. 外部に影響のある副作用だけをテストしよう

外部に公開しているAPIのテストケースが保たれていれば、リファクタリングのために内部実装を変えることもできます。

最後に

以下の記事も参考になる記事として紹介されていました。

MiniTest::SpecってRSpecと似たような形でテストが書けるんですね。はじめて知りました。(恥ずかしながらMiniTest::Unitしか知らなかったです・・・)

僕はこう思うです

僕は境界条件に沿ってcontextを書いていくので、かなりネストしがちなテストコードを書いていたりもします。とはいえ、コードを読む人に何を伝えたいのか?という意識の方が、規約を守ることよりも重要なのではないでしょうか。境界条件を伝えたいのであれば、境界条件が分かるようにテストを書くべきです。

コードを読む人に伝えるべきことを簡潔に伝えることができている、そういったテストコードこそがメンテナブルなのではないかと思います。

Railsのテストと言えば

Railsのテストと言えば、最近弊社の@jnchitoがEveryday Rails Testing with RSpecの翻訳プロジェクトを開始したようです。洋書の方、僕も持っているのですが、かなりの良著です。これが日本語訳されることは、とても価値が高いことだと思います。興味のある方/翻訳プロジェクトに成功して欲しい!と思ってくれる方は、是非こちらのランディングページから、メールアドレスを登録して下さい。

(参考)Everyday Rails Testing with RSpecの翻訳プロジェクトを開始しました!