【Rails】Railsのモデルテストとシステムテストを書いてみる(test-unit)
先日フィヨルドブートキャンプでテスト技法について学習したのでブログにまとめます。 今回のプラクティスでRailsの課題用に作成されたappにモデルテスト(単体テスト)とシステムテスト(結合テスト)を書く課題があったので学習して学んだ点を書いていきます。
まず、テストで使うtest-unitですが、これはruby標準のテスティングフレームワークで、minitestをベースにしたものです。
■単体テスト
どのような単位でテストを行うかはプログラミング言語の種類や開発者、プロジェクトの方針によっても異なります。ただ、多くの場合はクラスやメソッド、関数など、言語仕様上ほかのプログラムから一つのまとまりとして扱われる最小の単位ごとに行われることが多くそれを単体テストと呼びます。
■結合テスト
単体テストに対して複数のモジュールを組み合わせて正しく連結できるかどうかを調べるテストを「結合テスト」「統合テスト」「連結テスト」「インターフェーステスト」などと呼びます。システム全体を対象に行うテストは「システムテスト」というそうです。
■結論(テストを書いて思ったこと)
テスト課題をして、テストする項目をどこまでテストするかは要件や考え方にもよって人それぞれなので難しいな〜と思いました。例えば、本のappのテストで目的はDBから何らかの値を画面に表示できているかをテストするのであれば全ての項目(タイトル、内容、著者、作成日など)をテストしなくてもよかったりします。調べるポイントを見極めて、何がテストできていればOKなのかを判断するのは難しい! 私は全てをテストしようとしていました...笑 また、テストが通ったのでOKではなく、失敗することを確認するまでが1つのテストで失敗するテストを怠ってはいけないと反省しました。
■モデルテスト(単体テスト)で学んだ点
不要なファイルや使っていないfixture、変数は削除する
Time.zone.today
とDate.current
は両方今日の日付を取ってきてくれる。Railsのapplication.rb
ファイルのタイムゾーンの設定から日付を持ってくるのでTokyo時間の設定にしているか要確認!created_on
とは?:作成日(date)。created_at
が作成日時で、created_on
は日にちだけ返すメソッド
self.from_omniauthメソッドの単体テスト
def self.from_omniauth(auth) find_or_create_by(provider: auth.provider, uid: auth.uid) do |user| user.name = auth.info.name user.email = auth.info.email user.password = Devise.friendly_token[0, 20] end end
self.from_omniauth(auth)
の引数に何が入っているのか調べると、omniauth_callbacks_controller.rb
ファイルのgithubメソッドに記載してあるUser.from_omniauth(request.env['omniauth.auth'])
のrequest.env['omniauth.auth']
の部分が渡されているrequest.env['omniauth.auth']
というリクエストパラメータには、OmniAuthによってHashのデータ構造に似たOmniAuth::AuthHash
というクラスのオブジェクトが格納されているOmniAuth::AuthHash
クラスのオブジェクトのテストモードをOmniAuth.config.test_mode = true
で設定する- モック(テストサンプル)を作るにはmock_authを使うと、結合テスト中に認証プロバイダごとの認証ハッシュなどを返すことができる
参考:[Devise How-To] OmniAuth: 結合テスト(翻訳)|TechRacho(テックラッチョ)〜エンジニアの「?」を「!」に〜|BPS株式会社
class UserTest < ActiveSupport::TestCase test '#self.from_omniauth' do OmniAuth.config.test_mode = true OmniAuth.config.mock_auth[:github] = OmniAuth::AuthHash.new( { provider: 'github', uid: '12345', info: { name: 'carol', email: 'carol@example.com' }, credentials: { token: Devise.friendly_token[0, 20] } } ) assert User.from_omniauth(OmniAuth.config.mock_auth[:github]) end
■システムテスト(結合テスト)で学んだ点
削除した項目を確認するテストは
assert_no_text
を使って削除した項目がないことを確認できる今日の日付がviewで表示されているかを確認するときは、
assert_text Date.current.strftime('%Y/%m/%d')
で確認できる。Rubyのstrftime
メソッドは与えられた雛型で日付を書式できる。 Date#strftime (Ruby 3.0.0 リファレンスマニュアル)同じ画面にユーザ名が2つ:例えばAさんでログイン中とコメントの作成者にAさんと表示されていた場合にコメントを削除するテストでは、
with in
でclassの範囲指定して記載されているのかを確認するテストができる ※画面に表示されている数だけ調べたい場合であればassert_text 'Aさん', maximum: 2
とテストを書くこともできる
within '.class名' do assert_no_text 'Aさん' end
まとめ
- テストは失敗することも必ず確認してテストを書くようにする。