【週末Rails勉強会】Ruby on RailsでRSpecを使用してテスト駆動開発

ruby開発
スポンサーリンク
Railsでテストコード書きたいけど、何使えばいいか分からない・・・。
標準でMinitestっていうフレームワークが入ってはいるが、なにやらRSpecっていうテストフレームワークが主流らしいからとりあえず触ってみよう、しかし右も左も分からない・・・という事で少し調べてみました。
スポンサーリンク

RSpecとは

RSpecとは、Ruby におけるBDD (behavior driven development、ビヘイビア駆動開発) のためのテストフレームワークです。

ビヘイビア駆動開発
 
テスト駆動開発で記述されるテストケースは、作成したプログラムの動作が正しいかどうかを検証するために行う「テスト」である。テストであるという点は同一であるが、加えて、これから作成しようとするプログラムに期待される「振る舞い」や「制約条件」、つまり「要求仕様」に近い形で、自然言語を併記しながらテストコードを記述する。テストフレームワークのメソッド名も自然言語(英語など)に近い形をとっている。
テストコードの可読性があがる上、テストコードが要求仕様となりうる。要求仕様からテストコードを起こす際も、スムーズにコードに移行しやすい。
BDDではスペック(仕様)とテストは限りなく近い物である。従って、テスト駆動開発における「テストファースト」は、BDDにおいては「スペックファースト」となり、スペックを作ってから実装するという、より自然な形でのプログラム製作を実現している。
いくつかのテストフレームワークは、
アプリケーションの振る舞いを記述するストーリーフレームワーク
オブジェクトの振る舞いを記述するスペックフレームワーク
の2種類を含む。
出典元:wikipedia

小難しい事が書かれているが、要はテストするって事だよね、私、覚えました。

RailsへRSpecの導入

環境

  • Ruby 2.6.1
  • Rails 5.2.2 

導入方法

  1. Gemファイルへ記入(現在の最新版)
    group :development, :test do
      gem 'rspec-rails', '~> 3.8'
    end
  2. bundle install
  3. rails g rspec:install
    下記ファイル群が生成される

    create  .rspec
    create  spec/spec_helper.rb
    create  spec/rails_helper.rb
最低限の導入設定はこれで良いです。
細かな便利設定などはググると色々出てくるのでそちらを参考に。
この状態で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修正

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 に日本語を記述するともちろん上記のエラー文言が日本語になる。なるほど、便利だな。

参考サイト

公式サイトと、公式ドキュメントです。ドキュメントはRelishというサイトなので注意。

コメント