質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.47%

  • Ruby

    9654questions

    Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

  • Ruby on Rails

    9057questions

    Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Rails:テストのユーティリティのアプリ側と同じ関数を用意する理由

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 810

mitsuru793

score 149

現在、Ruby on Rails チュートリアルのソースコードをgithubからダウンロードして、勉強のために閲覧しています。 Twitterのようにつぶやいたことを表示するアプリです。

テストに使うユーティリティファイルについて質問があります。下記のようにテスト用にsing_inの関数が作られていますが、app/helpersにも既に同名のクラスがあります。

#spec/support/utilities.rb
def sign_in(user, options={})
  if options[:no_capybara]
    # Sign in when not using Capybara as well.
    remember_token = User.new_remember_token
    cookies[:remember_token] = remember_token
    user.update_attribute(:remember_token, User.digest(remember_token))
  else
    visit signin_path
    fill_in "Email",    with: user.email
    fill_in "Password", with: user.password
    click_button "Sign in"
  end
end
#...

#app/helpers/sessions_helper.rb
module SessionsHelper

  def sign_in(user)
    remember_token = User.new_remember_token
    cookies.permanent[:remember_token] = remember_token
    user.update_attribute(:remember_token, User.digest(remember_token))
    self.current_user = user
  end

  def signed_in?
    !current_user.nil?
  end
#...

テスト用のユーティリティをわざわざ作らずに、SessionsHelperにあるsing_inを使うのは良くないのでしょうか?テスト用のはcapybaraを使わない時のオプションを用意してありますが、今回はcapybaraを使う前提でtutorialが進められています。これは今後capybaraが廃止された場合に備えてかなと思ったのですが、それだと他のテストコードにも影響があるからここだけ対策をしてもあまり意味が無いように思えました。

このようにわざわざ同じ目的を達成できる関数をアプリ側とテストのヘルパー側に用意する必要性がわかりません。どなたか教えて頂けないでしょうか?テストのヘルパー側にも同じ関数を用意したら、それもテストする必要性が出てくると思います。
よろしくお願い致します。
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+1

テスト用のユーティリティをわざわざ作らずに、SessionsHelperにあるsing_inを使うのは良くないのでしょうか?

私見ですが、アプリ用のヘルパーとテスト用のヘルパーでは目的が異なります。全く同じ操作をしているからと言って一緒にするのはいささか乱暴と考えます。
アプリ用のSessionHelperは、Controllerでのログイン処理を補助するHelperです。WEBRick等がリクエストを受けて、ログイン処理が必要な時に呼ばれるHelperです。
テスト用のヘルパーは、テストの時に行うログイン処理を補助するHelperです。RSpec等から呼び出されます。そのログイン操作をシミュレートするためのヘルパーがテスト用のヘルパーです。

アプリとテストのヘルパーが同じにならない例をあげてみますね。1つはTwitterアカウントを使うログインでしょうか。Twitterを経由しないとアプリケーションのテストができないのは不便です。Twitterからログインしたかのようにシミュレートできればいいので、別の方法を取るでしょう。

ちなみに、Capybaraはブラウザの操作をシミュレーションできるエンドツーエンドテスト用ライブラリです。内部ではSelenium等を使ってブラウザの操作を自動化します。:no_capybaraオプションはユニットテスト等、レベルの異なるテストの時に使うことを意図したヘルパーメソッドではないでしょうか?

参考: capybara で快適なテスト生活を

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/08/19 16:26

    例を掲示してくださり、ありがとうございます。
    Twitterにログインする部分を書かずに、擬似的なコードでTwitterにログインしたと見せかけてテストを行うわけですね。つまり、テストヘルパーはシュミレートが目的だと思いました。

    参考リンクを拝見しましたが、次の意味がわかりませんでした。
    > レベルの異なるテストの時に使うことを意図したヘルパーメソッド
    レベルとはどのようなレベルのことなのでしょうか?恐縮ですが、何か具体例を教えてくださると大変幸いです。

    キャンセル

  • 2015/08/19 16:36

    ここでいうレベルとは、テスト対象の規模を指しています。ユニットテストはテスト対象のクラスただ1つを対象にしたテストです。Modelに実装した処理の検証が主な目的になるでしょう。ファンクショナルテストは複数のクラスを対象にしたテストです。アプリケーションの機能を検証する事を目的にします。RailsだとControllerとModelを組み合わせたテストになるはずです。エンドツーエンドテスト(E2Eテスト)はブラウザで操作するテストです。E2Eテストは、Webアプリケーション全体のテストなので、JavaScript等も絡んできます。

    「テストから見えてくるGoogleのソフトウェア開発( http://www.amazon.co.jp/dp/482228512X )」という本に、より具体的な例があります。こちらの本では、Sテスト、Mテスト、Lテスト、Eテストというように、よりテスト対象の大きさをベースにした名前がついています。そちらを読んでみるとよいでしょう。

    キャンセル

  • 2015/08/19 16:46

    なるほど。capybaraはE2Eテストに使うもので、ブラウザでレンダリングが出来ない部分のユニットテストの場合のために、no_capybaraオプションがあるのですね。

    各規模に見あったテスト方法、またその時に使えるライブラリや機能が違うことがわかりました。また、参考書籍の掲示も役立ちました。
    kompiroさんの説明はとても身になりました。ありがとうございました。

    キャンセル

+1

ユニットテストとなんだろうと、銀の弾丸となるツール・開発手法・開発プロセスはありません。適用して効果的なプロジェクトもあれば、逆効果となるプロジェクトもあります。本当にユニットテストが効果的となるプロジェクトであるかは検討した上で導入すべきです。
ユニットテストが効果的なプロダクトとは、開発チームが固定または大きく変動せず、長期にわたってメンテナンスが行われ、比較的に頻繁なリリースが行われるプロダクトです。これらの要素を満たしていないほどユニットテストの効果は小さくなり、費用対効果を考えた上で導入するか否かを検討すべきです。
例えば、開発チームがあまりにも変動的すぎると、テストコードのメンテナンスコストが高くなります。プロダクションコードだけでも追うのが大変な状況で、テストコードも同じように追っていかなくてはならないのですから当然です。テストコードが読みやすく整理されていることも必要です。いきなり渡された数千件にも渡るテストケースをメンテできるはずがありません。
プロトタイプのように、短期間で寿命を全うするようなプロダクトではユニットテストの効果は小さくなります。なぜならばユニットテストは自動化され、何度でも実行するからこそ、テストコードを書くコストが回収できるからです。1回だけテストを行うだけならば手動テストの方が効率がよい場合もあります。
リリースが1年に1回のように長期スパンである場合も同様です。手動テストのコストが相対的に小さくなるため、テストを自動化するメリットが小さくなります。逆に2週間に1回など頻繁なリリースを行う場合、手動テストだけでは太刀打ちできなくなるでしょう。個人的な目安としては3ヶ月に1回程度のリリースがないと大きなメリットとはならないと感じます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/08/19 14:01

    具体的な目安がとても参考になりました。
    お答え頂き、ありがとうございます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.47%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • Ruby

    9654questions

    Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

  • Ruby on Rails

    9057questions

    Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。