ウェブサービスを作っています。

active_decorator-rspec gem が便利

Active Decorator の decorator 内で、ヘルパーのメソッドを使っていると、テストをうまく書けないという問題があります。

今までは、

active_decorator のdecoratorをrspecでテストする方法 - アジャイルSEを目指すブログ

を参考にさせていただいていたのですが、これだと、ApplicationController に書いた helper_method がテストで使えないようです。

悩んでいたところ、active_decorator-rspec という便利な gem を見つけました。

Gemfile は、こんな感じ。

gem 'active_decorator'

group :test do
  gem 'active_decorator-rspec', require: false
  gem 'rspec-rails', group: 'development'
end

あとは、spec/rails_helper.rb で

require 'active_decorator/rspec'

と読み込んで、

spec/decorators 内のテストで、

describe UserDecorator, '.hoge' do
  let(:user) { User.new }
  subject { decorate(user).hoge }
end

のように使えます。

最新版の Redis を wercker で使う

wercker/install_redis.sh

if [ ! -d "$WERCKER_CACHE_DIR/redis" ]
then
    mkdir $WERCKER_CACHE_DIR/redis
fi

if [ ! -f "$WERCKER_CACHE_DIR/redis/redis-3.0.2.tar.gz" ]
then
    cd $WERCKER_CACHE_DIR/redis
    wget http://download.redis.io/releases/redis-3.0.2.tar.gz
    tar zxvf redis-3.0.2.tar.gz
    cd redis-3.0.2
    make
    sed -r "s#^daemonize no\$#daemonize yes#;" redis.conf > redis.conf.new
fi

cd $WERCKER_CACHE_DIR/redis/redis-3.0.2
sudo src/redis-server redis.conf.new

wercker.yml

build:
    steps:
        - script:
            name: install redis
            code: sh wercker/install_redis.sh

RSpec で Active Job のテストを書く

追記(2016/11/11 10:33):

この記事の内容は古くなっており、あまりおすすめしません。RSpec 公式の方法をお使い下さい。

追記ここまで


Rails 4.2.1 で確認しています。

Post#ping で、10 分後に PingJob をエンキューするというテストを書いてみます。


spec/rails_helper.rb

RSpec.configure do |config|
  config.include ActiveJob::TestHelper
  config.include ActiveSupport::Testing::TimeHelpers  # 時間関係のテスト (travel_to メソッド) で使用
  ...
end

app/jobs/ping_job.rb

class PingJob < ActiveJob::Base
  queue_as :default

  def perform(msg)
    # do something...
  end
end

app/models/post.rb

class Post < ActiveRecord::Base
  def ping
    PingJob.set(wait: 10.minutes).perform_later 'hello'
  end
end

spec/models/post_spec.rb

require 'rails_helper'

describe Post, '#ping' do
  before { @post = Post.new }

  it '10 分後に PingJob をエンキューする' do
    time = Time.current

    travel_to(time) do
      assertion = {
        job: PingJob,
        args: ['hello'],
        at: (time + 10.minutes).to_i,
      }
      assert_enqueued_with(assertion) { @post.ping }
    end
  end
end

参考

エラー監視サービス「Rollbar」を使う

エラー監視サービス「Rollbar」の設定メモです。

同種のサービスと比べて、無料なのにサイト登録数が無制限というメリットがあります。

エラー発生数によって課金されますが、監視頻度を設定することで、課金を抑えることができます。

タイムゾーンの設定

プロジェクトの Settings - General のページから。

Timezone を Asia - Tokyo に変更。Description も一応設定しておきます。

f:id:milk1000cc:20150208102354p:plain

エラー監視頻度の設定

Settings - Project Access Tokens のページから。

例えば、post_server_item を 10 items every 1 minute にします。

短期間に同じエラーが大量発生して、課金されてしまう可能性を下げることができます。

f:id:milk1000cc:20150208101627p:plain

通知の設定

Settings - Notifications のページから。

Email で、3 ルールだけ適用しています。

f:id:milk1000cc:20150208101628p:plain

CarrierWave で ConoHa オブジェクトストレージを使う

転送量無料で 100GB あたり 450 円/月という ConoHa オブジェクトストレージCarrierWave から使う方法です。

公開設定にすることで、画像サーバとして使うことができます。

CarrierWave のバージョンは 0.10.0、fog のバージョンは 1.24.0 で確認しています。

公開設定でコンテナを作成する

まず、公開設定でコンテナを作成します。

ConoHa のコントロールパネルからは公開設定のコンテナを作成できませんので、プログラムで作成します。

必要な情報は、コントロールパネルの「アカウント - API」( https://cp.conoha.jp/Account/API/ ) に掲載されています。

require 'fog'

CONOHA_TENANT_NAME = (テナント名)
CONOHA_USERNAME = (ユーザー名)
CONOHA_API_PASSWORD = (API パスワード)
CONOHA_API_AUTH_URL = (API Auth URL)
CONOHA_CONTAINER_NAME = (作成するコンテナ名)

service = Fog::Storage.new(
  provider: 'OpenStack',
  openstack_tenant: CONOHA_TENANT_NAME,
  openstack_username: CONOHA_USERNAME,
  openstack_api_key: CONOHA_API_PASSWORD,
  openstack_auth_url: CONOHA_API_AUTH_URL + '/tokens',
)

service.put_container(CONOHA_CONTAINER_NAME,
  public: true, headers: { 'X-Web-Mode' => 'true' })

CarrierWave の設定

Gemfile

gem 'carrierwave'
gem 'fog'
gem 'dotenv-rails'

config/initializers/carrierwave.rb

CarrierWave.configure do |config|
  if Rails.env.production?
    config.fog_credentials = {
      provider: 'OpenStack',
      openstack_tenant: ENV['CONOHA_TENANT_NAME'],
      openstack_username: ENV['CONOHA_USERNAME'],
      openstack_api_key: ENV['CONOHA_API_PASSWORD'],
      openstack_auth_url: ENV['CONOHA_API_AUTH_URL'] + '/tokens',
    }
    config.fog_directory = ENV['CONOHA_CONTAINER_NAME']
    config.storage :fog
    config.asset_host = ENV['CONOHA_ASSET_HOST'] + '/' +
      ENV['CONOHA_CONTAINER_NAME']
  else
    config.storage :file
  end
end

.env

CONOHA_TENANT_NAME=(テナント名)
CONOHA_USERNAME=(ユーザー名)
CONOHA_API_PASSWORD=(API パスワード)
CONOHA_API_AUTH_URL=(API Auth URL)
CONOHA_CONTAINER_NAME=(コンテナ名)
CONOHA_ASSET_HOST=(オブジェクトストレージエンドポイント)

以上で、production 環境のときは ConoHa オブジェクトストレージにデータが保存されます。