2016-10-12

初心者がRails+DeviseでTodoアプリ作る【RSpec・Travis CI・Rubocop】

前回は認証までだったので、今回はテストコード関連の以下のタスクをやっていきます。

Rubocop

Rubocopは静的コードチェックツールになります。インストールはGemfileに以下を記載して、bundle installすればOKです。
gem 'rubocop', require: false

あとはコマンドを実行するだけで、Rails用のコマンドは以下になります。

$ rubocop -R

.rubocop.ymlに記載する場合はこんな感じで記載します。

Rails:
  Enabled: true

ActiveAdminで自動生成したコードやdbディレクトリ以下のコードを無視したい場合は以下のように設定します。

AllCops:
  Exclude: 
   - 'app/admin/**/*'
   - 'db/**/*'

factory_girl

rspecの前にまずはfactory_girlをインストールします。factory_girlとはテスト用のレコードを作成するgemになります。

Railsで使う場合は以下をGemfileに書けばOK。

gem 'factory_girl_rails'

rspecでディレクトリを一通り作成したら、spec/factories/factory.rbを作成します。spec/factories/*.rbのファイルは自動的にロードされます。

FactoryGirl.define do
  factory :user do
    email 'hoge@example.com'
    password 'password'
    password_confirmation 'password'
    confirmed_at Date.today
  end

  factory :task do
    title 'hoge'
    description 'aaa'
  end
end

spec/support/factory_girl.rbも作成します。support以下のファイルを自動的にロードするようにrspecのところで設定します。

RSpec.configure do |config|
  config.include FactoryGirl::Syntax::Methods
end

こんな感じで呼び出すとfactoryで定義したレコードを作成できます。

FactoryGirl.create(:user)
FactoryGirl.create(:task, user: user)

RSpec

RSpecはBDDのフレームワークになります。

Railsの場合は以下をGemfileに記載してインストールします。

gem 'rspec-rails', '~> 3.5'

RSpecの初期設定は以下のコマンドで行います。これによってspecディレクトリが作成されます。

$ rails generate rspec:install

spec/rails_helper.rbを書き換え。supportディレクトリ以下のファイルを自動ロードして、テスト時のログを標準出力に出すようにします。これによってputsメソッドを使った、テスト時の簡易的なデバッグが出来ます。

Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
Rails.logger = Logger.new(STDOUT)

RSpec.configure do |config|
  ...
  config.extend ControllerMacros, :type => :controller
  config.include Devise::Test::ControllerHelpers, :type => :controller
  ...
end

spec/support/controller_macros.rbを作成します。Deviseの認証をテスト上で行うための仕掛けになります。sign_inメソッドの引数のuserはspecファイル毎に定義しています。

module ControllerMacros
  def login_user
    before(:each) do
      @request.env["devise.mapping"] = Devise.mappings[:user]
      sign_in user
    end
  end
end

コントローラのテスト↓

require 'rails_helper'

RSpec.describe TasksController, type: :controller do

  login_user

  let(:user) { FactoryGirl.create(:user) }
  let(:task) { FactoryGirl.create(:task, user: user) }

  describe 'GET #index' do
    it 'returns http success' do
      get :index
      expect(response).to have_http_status(:success)
      expect(response).to render_template('index')
      expect(assigns(:tasks)).to eq []
    end
  end

  describe 'POST #new' do
    it 'returns http success' do
      post :create, params: { task: { title: '123', description: 'hogehoge' } }
      expect(response).to have_http_status(302)
      expect(Task.all.count).to eq 1
      expect(Task.all.take.title).to eq '123'
      expect(Task.all.take.description).to eq 'hogehoge'
      expect(Task.all.take.user).to eq user
      expect(Task.all.take.completed_at).to eq nil
      expect(Task.all.take.completed).to eq false
    end
  end
end

ビューのテスト↓

require 'rails_helper'

RSpec.describe 'tasks/show.html.erb', type: :view do
  let(:user) { FactoryGirl.create(:user) }
  let(:task) { FactoryGirl.create(:task, user: user) }
  before do
    assign :task, task
    render
  end
  it 'should show all tasks' do
    expect(rendered).to match(/Title/)
    expect(rendered).to match(/Description/)
    expect(rendered).to match(/#{task.title}/)
    expect(rendered).to match(/#{task.description}/)
  end
end

Travis CI連携

CIサーバとも連携して自動テストをしてみます。今回はTravis CIを使います。

まずは.travis.ymlをアプリのルート直下に配置。

language: ruby
rvm:
  - 2.2.4
script:
  - bin/rake db:migrate RAILS_ENV=test
  - bin/rake

あとはTravis側でgitリポジトリを選択して有効化すればOK。pushされると自動的にテストが回ります。rspecをロードするとデフォルトのrakeタスクがspecになるようです。

テスト結果のステータスをREADMEに記述したい場合は、Travis CIのUI上で画像表示のMarkdownを取得すればOK

travisci_status_image_markdown

これだけだとテストを回すだけなので、Herokuへのデプロイもやっちゃいます。

まずはtravisコマンドをインストール

$ gem install travis -v 1.8.2 --no-rdoc --no-ri

以下のコマンドで暗号化したAPI KEYを.travis.ymlにセットアップ

$ travis encrypt $(heroku auth:token) --add deploy.api_key

その他Herokuの設定を.travis.ymlに書く↓

deploy:
  provider: heroku
  api_key:
    secure: {ENCRYPTED HEROKU API KEY}
  app: {HEROKU APP NAME}
  run: "rake db:migrate"

あとはPushしてテストが回ってOKであれば自動デプロイしてくれます。Travis簡単すぎてヤバイ。

参考URL

このエントリーをはてなブックマークに追加