KazumaLab.

流行りとリラックマと嵐が大好きです。

RailsのプロジェクトにRSpecを導入したお話

かずまです。

前回の記事で徳島を紹介するサイトを作ったお話をしました。
今回はそのRailsプロジェクトにテストコードを書いていこうということでRSpecを導入しました。

RSpec

github.com

Ruby用のGemもありますが、今回はRailsのプロジェクトということrails_rspecをインストールします。
Gemfileの中に書いてbundle installです。

忘れないうちにrspecの初期化をやっておきます。

$ rails g rspec:install

ちなみにテスト用のデータベースを用意する必要があるので、MySQLを使っている方などはRakeでRAILS_ENV=testを指定して作って上げる必要があります。

qiita.com
そこら辺はここを参考にするといいかも。

あとはGoogleで"rails mysql env"とかで検索すると情報が出てきますね。

テスト用のテストコードを書く

RSpecをインストールされるとspecディレクトリが出来ています。
ここにディレクトリを作成してRSpecのコードをカタカタ打っていきます。

ひとまずサンプルコードを書きたいと思います。
まずは言語のはじめに必ず書くとされる"Hello world!!"を出力してみます。

require 'rails_helper'

RSpec.describe ApplicationHelper, :type => 'helper' do
  describe "sample spec" do
    it "should print" do
      p "Hello World!!"
    end
  end
end 

いいですね。これで後は

rspec spec/sample/sample_spec.rb

ここで僕の場合、以下の様なwarningが...

DEPRECATION WARNING: alias_method_chain is deprecated. Please, use Module#prepend instead. From module, you can access the original method using super. (called from <top (required)> at /Users/kazuma/Documents/github/Prefecture/config/environment.rb:5)
DEPRECATION WARNING: alias_method_chain is deprecated. Please, use Module#prepend instead. From module, you can access the original method using super. (called from <top (required)> at /Users/kazuma/Documents/github/Prefecture/config/environment.rb:5)

これはググったところ、Rails5がサポートしていないGemがあるそうで、その警告でした。
まぁ警告してくれるのはありがたいですが毎回出るのは面倒なので切っておきます。

書くのはconfig/application.rb

ActiveSupport::Deprecation.silenced = true

これで消えました...!
あとは色々書いていくんですね。

Controllerのテストを書いてみる

今回はPictureという名前のモデルを使います。
そのPicturesControllerをテストします。

まずはRSpecのコード。

require 'rails_helper'
RSpec.describe PicturesController, :type => :controller do
  describe "GET #index" do
    it "respons success with an http 200 status code" do
      get :index
      expect(response).to be_success
    end

    it "renders the index template" do
      get :index
      expect(response).to render_template("index")
    end
  end
end

itの後ろは目的を書くらしいです。
何をするためのテストか?みたいな。

後は動作した結果、こうなってほしいというのを書くだけですね。
今回だとindexのレスポンスのステータスが200だと嬉しいよねってことでhave_http_status(200)です。

やる動作とそれに対応する返ってきてほしいものをit ... endの間に書くんでしょうね。

これはサンプルとか結構出回ってるので書いたという問題ではないけど....。
ちなみにここらへんを見るといっぱい書いてます。

File: README — Documentation for rspec-rails (3.6.0)

そんでRspecで叩く!

$ rspec spec/controllers/pictures_controller_spec.rb

Failures:

  1) PicturesController GET #index renders the index template
     Failure/Error: expect(response).to render_template("index")
     
     NoMethodError:
       assert_template has been extracted to a gem. To continue using it,
               add `gem 'rails-controller-testing'` to your Gemfile.
     # ./spec/controllers/pictures_controller_spec.rb:12:in `block (3 levels) in <top (required)>'

Finished in 0.0513 seconds (files took 3.57 seconds to load)
2 examples, 1 failure

Failed examples:

rspec ./spec/controllers/pictures_controller_spec.rb:10 # PicturesController GET #index renders the index template

エラった、なんかgem rails-controller-testingを入れろ見たいなことを書いてますね。
念のためググって見る。

github.com
Readmeに書いてある、更にこっちも

github.com
Issueでも解決してるっぽい。

これを使ってみる。
Gemfileにgem rails-controller-testingを入れてbundle!!
localにも入れてもいいかも...と思ったけどまぁ今回は止めておくことにします。

入れ終わったら、今度こそ!

..

Finished in 0.06619 seconds (files took 2.64 seconds to load)
2 examples, 0 failures

通ったぽい!
これでガリガリテストも書けますね!

まとめ

すごく簡単に単体のテストができました。
次の課題としては一連の流れのテストと自動化ですね。

サービスとしてはテストの通ったものだけを入れたいので、CircleCIを使って検証します。

ついでにコード規約用のRubocopも導入してみました。
参考にしたURLはこちら。
qiita.com

最後に徳島を紹介するサービスはこちら!

tokushima.sinariovr.com

オープンデータとかも使っています。

余談

機械学習を始めようと思ってpyenv入れたり、pipでTensorflowとか入れてみたけどいまいち方法がわからなくてあたふたしてます。
Unityでゼルダも途中で終わっちゃってるので遺伝的アルゴリズムとかで最強の敵を作ったりしてもいいかなーと思って試行錯誤してる最中です。

時間かかりそうです。