Over the past several months we’ve been internationalizing the Rails app that I’ve been working on. There are all sorts of lessons we’ve learned from rolling an app out to 17 countries (and counting)— and suffice it to say that Biggie wasn’t wrong when he said: “Mo countries, Mo problems” (or something to that effect).

We have a thorough ‘full-slice’ set of tests that uses plain old RSpec + Capybara in lieu of Cucumber, and before each of these tests we log in as a user. Once we started adding more countries we needed to log in as different users and our test assertions began to vary. For example, business rules dictated that some view elements might not be displayed for a user in Europe, or the form that a Euro user sees will differ from the one a U.S. user sees. We needed to write tests accordingly and vary the locale of the test users logging in.

I decided to use the Rspec.configure block in a spec_helper.rb file so that it was very easy for us to control the locale of the user at the moment we were writing our tests. We did this via an option passed in to either the it/do or describe block:

describe "view widget for adjusting price" do
  it "calculates price with value added tax field for European users", :user_locale => :euro do
    ... test set up and assertion with VAT...
  end
end

or…

describe "view widget with no VAT calculation", :user_locale => :us do
  it "calculates price without VAT for U.S. users" do
    ... test setup and assertion without VAT...
  end
end

As I mentioned, the :user_locale option is handled back in our spec_helper.rb file. The configuation looks something like this: [UPDATE 2/10/2015: I came back to this post trying to use this myself and I realized that I now need to use metadata and I also wasn’t passing in example to the block.]

RSpec.configure do |config|
  config.before :each do |example|
    user_locale = example.metadata[:user_locale]
    login_for_location(user_locale)
  end
end

def login_for_location(user_locale)
  ... the login/token/auth code ...
end

The key here is example.options in the third line of the Rspec.configure block. All of your RSpec examples can take metadata so when we pass in the hash of :user_locale => :euro to a test example it is then available to us during the configuration. For further reading I recommend a quick look through the rspec-core source code on metadata.

There is one catch to be aware of, but the solution is rather simple (which dawned on me after looking at a project fellow 8th Light'er Myles Megyesi had set up). If you only have a certain amount of tests that require configuration then I wouldn’t recommend putting this login configuration inside of the main spec_helper.rb file— especially if you have a fork in your logic. It doesn’t make any sense for tests that have nothing to do with logging in or a locale to hit this configuration block. Instead, just create a second spec_helper file in the appropriate directory and only include it for those tests that need it. For example, we the locale configuration in spec/integration/locale/spec_helper.rb.