Last Updated: February 25, 2016
·
2.198K
· jandintel

Rails internationalization (I18n) tests

Just today I came across a post from Thoughtbot about testing internationalization (I18n) in your integration/features tests. However I don't quite agree on the way they're using internationalization in their tests. I purpose a different solution, let's compare:

Solution 1 (Thoughtbot)

spec/features/visitor_signs_in_spec.rb:

feature 'user views dashboard' do
  scenario 'sees welcome message' do
    user = create(:user)
    visit dashboard_path(as: user)

    expect(page).to have_content welcome_message_for(user)
  end

  def welcome_message_for(user)
    t('dashboards.show.welcome', user: user)
  end
end

They extract the explicit text from the test, and test based on what the translation returns. You would expect that this is fine, but what if the translation in the locales file changes? The test still passes, but something definitely changed. So you're not really testing your view then, only if the translation on the page shows the same thing as the translation your test. The big pro in this is that your flexible with your tests, but the big con is that the test not explicitly tests the content on the page.

How could we do it differently?

Solution 2

Keep your test the way Thoughtbot purposes, but test your translations explicitly.
spec/translations/en/dashboard_translations_spec.rb:

describe 'Dashboard translation' do
  describe 'translates' do
    it 'welcome message' do
      user = create(:user)
      expect(I18n.t('dashboards.show.welcome', user: user)).to eql("Welcome #{user.name}")
    end
  end
end

This solution will explicitly test if the translations in the locales file are correctly translated. This will allow you to stay flexible (pro) in your integration/feature tests and still test the translations. I could however understand that you get the feeling that your doing this a bit double work (con). But I think the tradeoff is worth it.

Side note: You could think about what you do and do not what to test explicitly. For example test: headers, titles, navigation, ect. explicitly, but fairly mutation/changing text like: marketing, updates, ect. not.

TL;DR: Make your integration/feature tests flexible with including I18n in your test, but still test for the explicit text with translation tests.