前回は認証までだったので、今回はテストコード関連の以下のタスクをやっていきます。
- Rubocopによる静的コードチェック
- RSpecによるテストコード作成
- TravisCIによるCI
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
これだけだとテストを回すだけなので、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
- How To: Test controllers with Rails 3 and 4 (and RSpec) · plataformatec/devise Wiki
- factory_girl/GETTING_STARTED.md at master · thoughtbot/factory_girl
- rspecでcontrollerをテストするときの基礎まとめ - びぼろく!
- RSpecにおけるFactoryGirlの使い方まとめ - Qiita
- Rails 5に移行した後にTravis CIのbundle exec rakeでエラーが出たら対処する方法 - Qiita
- Heroku Deployment - Travis CI