地方でリモートワーク in Iwate

東京の受託開発会社でリモートワークしてます。

RailsでI18nをRspecで自動テストする方法

スポンサーリンク

github.com

RailsでI18n対応しています。 ymlファイルに定義してviewでi18n.t('hoge')で呼び出してます。 conflict解消時にymlファイルの修正ミスでtranceration missing'のまま、開発ブランチにマージしてしまいました。 今後もこのようなことが起きてしまうと思い、自動的にymlファイルの定義ミスを検出する方法がないか調べてみるとやはりありました! gemi18n-tasksを使うとコマンド1つで検出できますし、Rspecに組みこむこともできます。

i18n-tasksの使い方

gemfile

group :test do
  gem 'i18n-tasks'
end
$ bundle install

i18n-tasksの設定ファイルを作成します。 ファイルはデフォルト定義がされています。

$ i18n-tasks config > config/i18n-tasks.yml

config/i18n-tasks.yml

internal_locale: en
base_locale: en
locales:
- en
- ja
data:
  adapter: I18n::Tasks::Data::FileSystem
  read:
  - config/locales/%{locale}.yml
  write:
  - config/locales/%{locale}.yml
search:
  paths:
  - app/
  relative_roots:
  - app/controllers
  - app/helpers
  - app/mailers
  - app/presenters
  - app/views
  scanners:
  - - "::I18n::Tasks::Scanners::RubyAstScanner"
    - only:
      - "*.rb"
  - - "::I18n::Tasks::Scanners::PatternWithScopeScanner"
    - exclude:
      - "*.rb"
      ignore_lines:
        opal: "^\\s*#(?!\\si18n-tasks-use)"
        haml: "^\\s*-\\s*#(?!\\si18n-tasks-use)"
        slim: "^\\s*(?:-#|/)(?!\\si18n-tasks-use)"
        coffee: "^\\s*#(?!\\si18n-tasks-use)"
        erb: "^\\s*<%\\s*#(?!\\si18n-tasks-use)"
  strict: true

Rspec用のファイルを作成します。

$ cp $(i18n-tasks gem-path)/templates/rspec/i18n_spec.rb spec/

こちらもデフォルトで定義されています。

spec/i18n_spec.rb

# frozen_string_literal: true
require 'i18n/tasks'

RSpec.describe 'I18n' do
  let(:i18n) { I18n::Tasks::BaseTask.new }
  let(:missing_keys) { i18n.missing_keys }
  let(:unused_keys) { i18n.unused_keys }

  it 'does not have missing keys' do
    expect(missing_keys).to be_empty,
      "Missing #{missing_keys.leaves.count} i18n keys, run `i18n-tasks missing' to show them"
  end

  it 'does not have unused keys' do
    expect(unused_keys).to be_empty,
      "#{unused_keys.leaves.count} unused i18n keys, run `i18n-tasks unused' to show them"
  end
end

下記コマンドでtranseration missingと使用されていない定義の一覧が表示されます。

$ i18n-tasks health

上記設定ファイルのままだとja.ymlに定義しているのにen.ymlに定義していないとエラーが起こります。 その時は下記のように設定を変更します。

internal_locale: en
base_locale: ja
locales:
- ja # enは削除

上記設定ファイルのままでen.ymlにja.ymlの定義をそのまま反映させたい場合は下記コマンドを打ちます。

$ i18n-tasks add-missing

rspecも上記のままだとunusedがあるとテストが通りません。今回はtranseration missigのみテストしたいため、下記のように変更します。

spec/i18n_spec.rb

# frozen_string_literal: true
require 'i18n/tasks'

RSpec.describe 'I18n' do
  let(:i18n) { I18n::Tasks::BaseTask.new }
  let(:missing_keys) { i18n.missing_keys }

  it 'does not have missing keys' do
    expect(missing_keys).to be_empty,
      "Missing #{missing_keys.leaves.count} i18n keys, run `i18n-tasks missing' to show them"
  end
end

これでI18nの自動テストが設定できました。これで安心してマージできます。

Ruby on Rails 4 アプリケーションプログラミング

Ruby on Rails 4 アプリケーションプログラミング

実践Ruby on Rails 4 現場のプロから学ぶ本格Webプログラミング

実践Ruby on Rails 4 現場のプロから学ぶ本格Webプログラミング

改訂3版 基礎 Ruby on Rails 基礎シリーズ

改訂3版 基礎 Ruby on Rails 基礎シリーズ

パーフェクト Ruby on Rails

パーフェクト Ruby on Rails