Railsでテストコード書きたいけど、何使えばいいか分からない・・・。
標準でMinitestっていうフレームワークが入ってはいるが、なにやらRSpecっていうテストフレームワークが主流らしいからとりあえず触ってみよう、しかし右も左も分からない・・・という事で少し調べてみました。
RSpecとは
RSpecとは、Ruby におけるBDD (behavior driven development、ビヘイビア駆動開発) のためのテストフレームワークです。
ビヘイビア駆動開発テスト駆動開発で記述されるテストケースは、作成したプログラムの動作が正しいかどうかを検証するために行う「テスト」である。テストであるという点は同一であるが、加えて、これから作成しようとするプログラムに期待される「振る舞い」や「制約条件」、つまり「要求仕様」に近い形で、自然言語を併記しながらテストコードを記述する。テストフレームワークのメソッド名も自然言語(英語など)に近い形をとっている。テストコードの可読性があがる上、テストコードが要求仕様となりうる。要求仕様からテストコードを起こす際も、スムーズにコードに移行しやすい。BDDではスペック(仕様)とテストは限りなく近い物である。従って、テスト駆動開発における「テストファースト」は、BDDにおいては「スペックファースト」となり、スペックを作ってから実装するという、より自然な形でのプログラム製作を実現している。いくつかのテストフレームワークは、アプリケーションの振る舞いを記述するストーリーフレームワークオブジェクトの振る舞いを記述するスペックフレームワークの2種類を含む。出典元:wikipedia
小難しい事が書かれているが、要はテストするって事だよね、私、覚えました。
RailsへRSpecの導入
環境
- Ruby 2.6.1
- Rails 5.2.2
導入方法
- Gemファイルへ記入(現在の最新版)
group :development, :test do gem 'rspec-rails', '~> 3.8' end
- bundle install
- rails g rspec:install
下記ファイル群が生成されるcreate .rspec create spec/spec_helper.rb create spec/rails_helper.rb
最低限の導入設定はこれで良いです。
細かな便利設定などはググると色々出てくるのでそちらを参考に。
この状態でrspecコマンドを叩くとテストが走ります。
細かな便利設定などはググると色々出てくるのでそちらを参考に。
この状態でrspecコマンドを叩くとテストが走ります。
スペック(spec)ファイルの作成
RSpecは一度インストールすると、rails generate model, rails generate controllerが使用されたときにTest :: Unitテストファイルの代わりにspecファイルを生成します。また、既存のものに対して作成したい場合はRSpecジェネレーターをこのように呼び出すことも可能です。
rails generate rspec:model
詳しくはこちらを参照
specファイルの記入方法
試しにコントローラーのspecファイルを作成してみる。まずは新規にtestコントローラーの作成をします。
rails g controller test
結果
create app/controllers/test_controller.rb invoke erb exist app/views/test invoke rspec create spec/controllers/test_controller_spec.rb invoke helper create app/helpers/test_helper.rb invoke rspec create spec/helpers/test_helper_spec.rb invoke assets invoke coffee create app/assets/javascripts/test.coffee invoke scss create app/assets/stylesheets/test.scss
specファイルも同時に作成されてることがわかります。
controller, helper それぞれに対応したファイルが作成されていますね。
controller, helper それぞれに対応したファイルが作成されていますね。
controller修正
class TestController < ApplicationController def index end end
routes修正
get 'test', to: 'test#index'
viewの作成
views/test/index.html.erbを作成します。
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>テストタイトル</title> </head> <body> <h1>Test Controller index</h1> <p>hogehoge</p> </body> </html>
specファイルの作成
test_controller_spec.rbを作成する。
require 'rails_helper' # TestControllerというコントローラーのテストをするよ RSpec.describe TestController, type: :controller do # indexメソッドがテスト対象だよ describe "#index" do # 正常に応答する it "responds successfully" do get :index expect(response).to be_success end end # 200ステータスが帰ってくる it "returns a 200 response" do get :index expect(response).to have_http_status "200" end end<br>
テスト実行
先ほど作成したファイルを指定して実行する。
rake spec SPEC=spec/controllers/test_controller_spec.rb
結果
Finished in 0.02228 seconds (files took 2.19 seconds to load) 2 examples, 0 failures
補足
- describe:テストの対象が何かを記述する。
- context:特定の条件が何かを記述する。(今回は書いてない)
- it:検証内容での振る舞いが何かを記述する。
- expect([評価の対象]).to [評価の方法(matcher)]
失敗するパターンも試して見たいので、routesをコメントアウトしてみる
# get 'test', to: 'test#index'
結果
Failures: 1) TestController returns a 200 response Failure/Error: get :index ActionController::UrlGenerationError: No route matches {:action=>"index", :controller=>"test"} # ./spec/controllers/test_controller_spec.rb:12:in `block (2 levels) in <top (required)>' 2) TestController#index responds successfully Failure/Error: get :index ActionController::UrlGenerationError: No route matches {:action=>"index", :controller=>"test"} # ./spec/controllers/test_controller_spec.rb:6:in `block (3 levels) in <top (required)>' Finished in 0.00952 seconds (files took 2.19 seconds to load) 2 examples, 2 failures Failed examples: rspec ./spec/controllers/test_controller_spec.rb:11 # TestController returns a 200 response rspec ./spec/controllers/test_controller_spec.rb:5 # TestController#index responds successfully
テストが失敗した際に it に記述した内容が表示されるようになっている。
また it に日本語を記述するともちろん上記のエラー文言が日本語になる。なるほど、便利だな。
また it に日本語を記述するともちろん上記のエラー文言が日本語になる。なるほど、便利だな。
参考サイト
公式サイトと、公式ドキュメントです。ドキュメントはRelishというサイトなので注意。
コメント