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

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

新規登録して質問してみよう
ただいま回答率
85.49%
Ruby

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

Ruby on Rails

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

Q&A

解決済

2回答

1750閲覧

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

mitsuru793

総合スコア157

Ruby

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

Ruby on Rails

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

0グッド

0クリップ

投稿2015/08/19 04:10

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

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

ruby

1#spec/support/utilities.rb 2def sign_in(user, options={}) 3 if options[:no_capybara] 4 # Sign in when not using Capybara as well. 5 remember_token = User.new_remember_token 6 cookies[:remember_token] = remember_token 7 user.update_attribute(:remember_token, User.digest(remember_token)) 8 else 9 visit signin_path 10 fill_in "Email", with: user.email 11 fill_in "Password", with: user.password 12 click_button "Sign in" 13 end 14end 15#...

ruby

1#app/helpers/sessions_helper.rb 2module SessionsHelper 3 4 def sign_in(user) 5 remember_token = User.new_remember_token 6 cookies.permanent[:remember_token] = remember_token 7 user.update_attribute(:remember_token, User.digest(remember_token)) 8 self.current_user = user 9 end 10 11 def signed_in? 12 !current_user.nil? 13 end 14#...

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

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

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

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

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

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

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

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

投稿2015/08/19 06:26

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mitsuru793

2015/08/19 07:26

例を掲示してくださり、ありがとうございます。 Twitterにログインする部分を書かずに、擬似的なコードでTwitterにログインしたと見せかけてテストを行うわけですね。つまり、テストヘルパーはシュミレートが目的だと思いました。 参考リンクを拝見しましたが、次の意味がわかりませんでした。 > レベルの異なるテストの時に使うことを意図したヘルパーメソッド レベルとはどのようなレベルのことなのでしょうか?恐縮ですが、何か具体例を教えてくださると大変幸いです。
退会済みユーザー

退会済みユーザー

2015/08/19 07:36

ここでいうレベルとは、テスト対象の規模を指しています。ユニットテストはテスト対象のクラスただ1つを対象にしたテストです。Modelに実装した処理の検証が主な目的になるでしょう。ファンクショナルテストは複数のクラスを対象にしたテストです。アプリケーションの機能を検証する事を目的にします。RailsだとControllerとModelを組み合わせたテストになるはずです。エンドツーエンドテスト(E2Eテスト)はブラウザで操作するテストです。E2Eテストは、Webアプリケーション全体のテストなので、JavaScript等も絡んできます。 「テストから見えてくるGoogleのソフトウェア開発( http://www.amazon.co.jp/dp/482228512X )」という本に、より具体的な例があります。こちらの本では、Sテスト、Mテスト、Lテスト、Eテストというように、よりテスト対象の大きさをベースにした名前がついています。そちらを読んでみるとよいでしょう。
mitsuru793

2015/08/19 07:46

なるほど。capybaraはE2Eテストに使うもので、ブラウザでレンダリングが出来ない部分のユニットテストの場合のために、no_capybaraオプションがあるのですね。 各規模に見あったテスト方法、またその時に使えるライブラリや機能が違うことがわかりました。また、参考書籍の掲示も役立ちました。 kompiroさんの説明はとても身になりました。ありがとうございました。
guest

0

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

投稿2015/08/19 04:43

piotcard

総合スコア69

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mitsuru793

2015/08/19 05:01

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問