9
\$\begingroup\$

Here I am trying to avoid hardcoding in flash messages by using I18n. Also, I have tried to use a CSS selector for submitting the form to make the tests less brittle (I don't really care that much about what the text on the button is - more what happens when submitting).

Is this a good approach for making tests less brittle due to translation changes?

RSpec.feature "Classic Authentication" do
 let(:submit) { find(:css, 'input[type="submit"]') }
 let(:user) { FactoryGirl.create(:user) }
 context 'Registation' do
 background do
 visit new_user_registration_path
 page.fill_in 'Email', with: '[email protected]'
 page.fill_in 'Password', with: 'P4ssword'
 page.fill_in 'Password confirmation', with: 'P4ssword'
 end
 scenario "when I sign up with valid info" do
 submit.click
 expect(page).to have_content I18n.t('devise.registrations.signed_up')
 expect(page).to have_content I18n.t('user.sign_out')
 end
 scenario "when I sign up with invalid info" do
 page.fill_in 'Email', with: 'testasdas'
 submit.click
 expect(page).to have_content 'Email is invalid'
 expect(page).to_not have_content I18n.t('devise.registrations.signed_up')
 end
 end
 context 'Log in' do
 background do
 visit '/'
 click_link I18n.t('user.sign_in')
 page.fill_in 'Email', with: user.email
 end
 scenario 'when I sign in with valid details.' do
 page.fill_in 'Password', with: 'P4ssword'
 submit.click
 expect(page).to have_content I18n.t('devise.sessions.signed_in')
 expect(page).to have_link I18n.t('user.sign_out')
 end
 scenario 'when I sign in with an invalid password' do
 page.fill_in 'Password', with: 'H4XX0R'
 submit.click
 expect(page).to_not have_content I18n.t('devise.sessions.signed_in')
 end
 end
end
Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Nov 14, 2014 at 9:22
\$\endgroup\$

2 Answers 2

9
\$\begingroup\$

Seems OK to me.

However, it might be nice to add a "macro" to let you skip the I18n. and just use t like you do in views.

And you can add some extra checks while you're at it, since you'll i18n want it to make noise when testing.

For instance, you could add a file like spec/support/macros/i18n_macros.rb with the following:

module I18nMacros
 def t(*args)
 I18n.translate!(*args)
 end
end

Using translate! will cause i18n to raise an exception if the translation you're looking for doesn't exist.

Then include it in spec_helper.rb

config.include I18nMacros

or alternatively include it for type: :feature specs only.

And if you haven't already (it's default for newer versions of Rails), set i18n to raise exceptions in your views (the above will only raise on the stuff in your tests). Put something like this in config/environments/test.rb

# Raises error for missing translations
config.action_view.raise_on_missing_translations = true
answered Nov 14, 2014 at 14:43
\$\endgroup\$
1
  • \$\begingroup\$ Nice, but I can't get RubyMine to complete the translations keys in I18nMacros::t which is a feature I find a little hard to live without. \$\endgroup\$ Commented Nov 15, 2014 at 23:24
2
\$\begingroup\$

My suggestions would be:

  1. Create a helper for common sign up and sign in logic:

    # E.g. spec/support/helpers/session_helpers.rb
    module Features
     module SessionHelpers
     def sign_up_with(email, password, confirmation)
     visit new_user_registration_path
     fill_in 'Email', with: email
     fill_in 'Password', with: password
     fill_in 'Password confirmation', with: confirmation
     click_button 'Sign up'
     end
     def signin(email, password)
     visit new_user_session_path
     fill_in 'Email', with: email
     fill_in 'Password', with: password
     click_button 'Sign in'
     end
     end
    end
    

    And include it in spec/support/helpers.rb:

    require 'support/helpers/session_helpers'
    

    And use it like this:

    scenario "when I sign up with invalid info" do
     sign_up_with('testasdas', '', '')
     expect(page).to have_content 'Email is invalid'
    end
    

    Courtesy Daniel Kehoe, comes for free if you use his awesome Rails Composer.

  2. Rather than a binary valid/invalid sign up test, you might want to be more fine grained by testing each field (email, password, password confirmation etc.) separately like in this example.

  3. Get rid of I18n . so you can use t(...) just like in views:

    # spec/spec_helper.rb
    RSpec.configure do |config|
     # ...
     config.include AbstractController::Translation
     # ...
    end
    

    Courtesy thoughtbot.

answered Aug 14, 2015 at 18:58
\$\endgroup\$
1
  • \$\begingroup\$ Thanks for the reply. Since I am using warden I can use the warden test helpers to sign in/out in the test setup. This is much faster than acually loading and posting the signup page. I just go though the actual front-end for feature specs which test the actual sign in process. \$\endgroup\$ Commented Aug 15, 2015 at 9:38

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.