Rails

【Rails】Railsのテストって難しい。Railsチュートリアルにも出てくるテストについて

Railsチュートリアルの7章まで進めましたが、テスト駆動型開発でテストをバリバリ記述していくのに悪戦苦闘してます。

使用されるテスト用のメソッドには特に詳しい説明もなく、いきなり出てくる感じになります。

assetとかassert_notとかとか・・・

これはMinitestとというRails標準のテストのためのフレームワークになります。

Minitestを使用することで、ルティング、各コントローラー間の処理、データーベースとのやり取り、メソッドの挙動やブラウザに返されるHTMLファイルの内容など、様々なものを簡単にテストすることができます。

聞くと便利そうですが、いざ使うとなるとスッと入ってこない箇所もあるので、今回はRailsチュートリアルにも出てくる、MInitestを使ったテストについてを解説していきます。

テストの目的

テストの目的は以下の通りです。

  • 機能が動作していることを保証する
  • 機能に修正を加えた時に「これまで動作していた機能が動作しなくなる」というリスクを最小限に抑える

テストを書くという手間は発生してしまいますが、バグや大規模な変更へのリスクが減り、機能に修正を加えた後にいちいちブラウザで手動でテストを行う手間が大幅に削減できます。

テストのフォルダ構成

テスト関連のフォルダは「rails new」を実行した時に「/test」に作成されます。

「/test」の構成は以下の通りです。

controllers コントローラ・ビュー・ルーティングをまとめたテストを保存するフォルダ
fixtures テストデータ生成用のファイルを保存するフォルダ
helpers ビューヘルパーのテストを保存するフォルダ
integration 複数のコントローラをまたいだテストを保存するフォルダ(統合テスト)
mailers メーラーのテストを保存するフォルダ
models モデルのテストを保存するフォルダ
system システムテスト(Javascriptなど)を保存するフォルダ
application_system_test_case.rb システムテストのデフォルト設定を記述するファイル
test_helper.rb テストのデフォルト設定を記述するファイル

テストファイルの作成方法

テスト用のファイルは、コントローラー作成時などに自動生成されるものと、専用のコマンドを実行して作成するものがあります。

controller コントローラー作成時に動生成
model、fixture モデル作成時に自動生成。
mailer メーラー作成時に自動生成
integration 「$ g integration_test ファイル名」で作成

基本的な文法

基本的な文法は以下のようになります。

まず、「require ‘test_helper’によって、test/test_helper.rbに記載されているデフォルト設定が読み込まれます。

全てのテストファイルに「require ‘test_helper’」は組み込まれるので、このファイルに追加したメソッドはテスト全体で使用することができます。

上記の「SampleTest」クラスは「ActiveSuppoort::TestCase」クラスを継承しておりい、「ActiveSupport::TestCase」クラスのスーパークラスはRuby標準のテスティングフレームワークである「Minitest::Test」クラスになります。

そのため、「Minitest::Test」のアサーションメソッドは全て利用することができます。

ちなみに「Minitest::Test」クラスの場合は以下のように、メソッド名に「test_」とついたものをテスト実行時にランダムに実行していくことになります。

しかし、Railsの場合、もっと読みやすいテスト名にすることができます。

testメソッドは引数に文字列とブロックを受け付けます。

「test “the sample”と記述することで、行頭にtestを追加し、スペースをアンダーバーに変更してくれます。
(上記の例だと、「test_the_sample」メソッドとなる)

testメソッドを使用することで、テストの命名に気を使わなくても済み、実際のテストコードはブロックに記述することになります。

このように記載したテストは以下のコマンドで実行できます。

「test」の部分は「t」と省略可能です。

setup/teardownメソッド

テスト実行前に毎回実行してほしい処理があれば、setupメソッドが使用できます。

Ruby標準のMiniTestでは上記のように「def setup」と書いていましたが、以下のように「setup do」と分かりやすい記法を使用することができます。

setupメソッドとは反対に、テスト実行後に行いたい処理があれば、teardownメソッドが使用できます。

setupやteardownメソッドはデータベースから決まった値を取得しておいたりなんかに使用できますね。

テスト(アサーション)のメソッド

アサーションとはRuby標準のMinitestで用意されている、テスト用のメソッドになります。

Railsチュートリアルでは不意にassert、assert_noとかが出てきて混乱しますが、これらは全てアサーションと呼ばれるメソッドになります。

代表的な例を下記していきます。

assert

testが真(nil、false以外)の場合にテストが成功します。

assert_not

testが偽の場合にテスト成功します。

assert_nil

オブジェクト.empty?が真の場合にテストが成功します。

assert_empty

オブジェクト.empty?が真の場合にテストが成功します。

assert_not_empty

オブジェクト.empty?が偽の場合にテストが成功します。

assert_equal

第1引数 == 第2引数が真の場合にテストが成功します。

assert_not_equal

第1引数 == 第2引数が偽の場合にテストが成功します。

assert_redirected_to

適切にリダイレクトされている場合にテストが成功します。

assert_response

レスポンスが指定したステータスコードになっている場合にテストが成功します。

assert_select

指定した種類、個数のHTML要素が存在する場合にテストが成功します。

assert_match

指定した正規表現に一致する場合にテストが成功します。

assert_difference

create/update/delete実行後のレコード数が指定通りに変化している場合にテストが成功します。

assert_no_difference

create/update/delete実行後のレコード数が指定通りに変化していない場合にテストが成功します。

まとめ

Railsのテストについてまとめてみましたが、いかかがだったでしょうか?

Railsチュートリアルでは不意にテストが出てくる且つテスト駆動型開発なので、まずテストを書いて行くことになるので、Rails初めてというかテストを書くといった習慣がない人はかなり戸惑うのではないかと思います。

今回紹介したテストメソッド(アサーション)は良く出てくる(Railsチュートリアルにも出てくる)ものに絞ってまとめています。

テストメソッドには他にも指定した例外が発生するかをテストするようなメソッドなど色々とあるので、新しいものに触れる度に加筆していきたいと思います。

テストをきちんと理解し、テスト駆動型開発を行うことで修正に強いプログラムが組めるようになっていきましょう。

Railsの中で使用されるRubyの本になります。

Railsチュートリアルをやる前にRubyはProgateなどで学習している方も多いかと思いますが、Progateからさらに発展したRubyの入門書になります。

RailsはRubyで記載するとはいえ、Rubyの文法にはあまり触れられないので、Railsチュートリアルを受けるための相棒としてオススメです。

ABOUT ME
Jyu2
ソフトウェア会社(SIer)で10年以上勤務のシステムエンジニア|ポケットWiFi使用歴2年以上|ポケットWiFi+αで快適でお得なインターネット環境を構築するための情報を発信|その他、IT情報やWebサービス、アプリ、ガジェットなどの情報を発信|自分と他の人のカバンの中身を紹介するメディア「カバンの中身ラボ(https://kaban-no-nakami-labo.com/)」も運営しています。 ポケットWiFi選びに迷ったらTwitter、お問合せフォームからご連絡ください。