Rspecを使ってRailsでテストしてみた話
Rspecを用いてRailsでテストを書いてみたのでそれの備忘録。 テストについてもよくわかっていなかったのでまとめてみた。
テストについて
テストは大きく分けて下記の三つである。
- ユニットテスト
- ファンクションテスト
- インテグレーションテスト
ユニットテスト(単体テスト)
プログラムを構成するできるだけ小さい単位(ユニット)の機能に対して正しく動作するかどうかを検証するテスト。 関数やメソッドに対して行われることが多く、関数やメソッドのバグを取り除く目的がある。 railsの場合ではモデルに対して行うテスト。
ファンクションテスト(機能テスト)
システム開発の際に行われるテストのうち、ユーザー側から要求された機能をシステムが満足しているかどうかを検証するテスト。 ユーザーから渡されたデータと処理の結果を比較するブラックボックステストなど中でどんな処理をされてるかなどのテストというよりは要求書通りにうまくいってるかを確認するのが目的である。 railsの場合ではアクションに対して行われる。
インテグレーションテスト(総合テスト)
システム全体に行うテストであり、最終確認のテスト。 サインアップからログインまでの流れなどの一連の流れのテスト。 railsではアクション間に対してのテスト。
Rspecの導入
Railsではデフォルトでテストユニットが用意されているがRspecを用いた自動テストの環境を整えテストをしやすくする。
Rspecのインストール
Gemfile
に以下のgemを追加してbundle install
group :test do gem 'rspec' gem 'rspec-rails' end
テストを書いてみた。
Model編
準備編
まず、Rspecを用いてテストするためのmodelクラスを一つ 用意する。以下のコマンドでモデルを作成する。
$ rails g model post title:string subtitle:string invoke active_record create db/migrate/20141030015802_create_posts.rb create app/models/post.rb invoke test_unit create test/models/post_test.rb create test/fixtures/posts.yml
次に作成したpostクラスをテストするためのRspecを用意する。
$ rails g rspec:model post create spec/models/post_spec.rb
最後に以下のコマンドを入力してtest用のデータベースを作成する。
$ rake db:migrate RAILS_ENV=test
これで準備は終了。
テスト編
コマンドによって生成されたテストファイルを見てみると以下のような感じになっている。
なにもテストが書かれてない状態なので早速テストを書いていく。フィールドのvalidationをテストする。 仮に今回のテスト項目は以下の4点であるとする。
- titleは空であってはいけない
- titleは5文字 ~ 40文字以内でなければならない。
- subtitleは空であってはいけない
- subtitleは200字を超えてはいけない
まずは上の4つの仕様が通る場合のテストデータと通らない場合のテストデータをfixtures/posts.yml
に書いていく。下のようなテストデータを書いた。
次にこれをテストデータを用いてテストを書いていく。
流れはテストデータを読み込んでそれを実行してみて期待している値と合致してるかどうかをチェックする。
expect
文の使い方は以下のリンクを参照。
rspec/rspec-expectations · GitHub
書いたテストを実行してみる。実行の方法は以下のコマンドである。
$ bundle exec rspec spec/models/......rb
まだ、validationになにも記述していないため、7個かいたテストのうち2つしか通らない。
postモデルにvalidationを記述してテストが通るようにする。
テストが無事に通るようになった〜!!
注意点
fixturesの書き方
fixturesはテストデータを読み込むためのファイルである。このファイル内ではタグを入れてはいけない。タグを入れたい気持ちをぐっと抑えてスペースを入れましょう。
Repecは元のテストとは違うディレクトリにあるので注意
Railsではデフォルトでテストツールが用意されている。それはプロジェクトのtestディレクトリ内にfixturesからいろいろ用意されているが、もちろんのことだがこれはRspecとは違うので注意が必要である。
Rspecはspecディレクトリである。(これに気づくまでに無駄に時間を食われた。)
fixturesを読み込み忘れに注意
デフォルトのテストツールではfixturesも自動で生成され、特に指定もなしに読み込んでくれるのだがRspecではfixtures :xxxx
と手動で入力しなければならないので注意。