Multi-Locale Cucumber Features
So here’s the problem: Your site is available in multiple languages. How do you write features that ensure everything works regardless of the language?
I can imagine some truly clever solutions to this problem. This isn’t one of them. Instead, this is a practical approach to solving the problem – with the assumption that you’re not using your features to communicate with non-technical stakeholders.
Let’s start with this simple feature describing a user logging in and viewing his profile, and then see how we can transform it to suit our needs:
Feature: User views profile
Scenario:
Given I am logged in as a normal user
When I go to the home page
And I follow "Profile"
Then I should see "Your Profile"
Step 1: Use your translation keys
Okay. While that feature might pass, it’s not going to work if we change the default locale – and it won’t even work if we change our translation keys, so let’s change it up a bit:
Given I am logged in as a normal user
When I go to the home page
And I follow t(profile)
Then I should see t(your_profile)
Pretty? No. But it should be familiar to anyone who’s used the I18n gem, and it’s super easy to plug into cucumber:
# features/step_definitions/locale_steps.rb
# Allows translation within cucumber features.
#
# When I follow t(self_generated)
# => When I follow "#{t(:self_generated)}"
#
Given(
/ ^
(.*) # I should see
(t\(([^)]+)\)) # t(self_generated)
(.*) # within "#main"
$
/x) do |first, _, key, last|
Given %Q[#{first}"#{t(key)}"#{last}]
end
Step 2: Test multiple locales
Now that we’re using our translation keys, we can enhance our feature to test against multiple locales. We’ll want something like this:
Feature: User views profile
Scenario:
Given my locale is "en"
And I am logged in as a normal user
When I go to the home page
And I follow t(profile)
Then I should see t(your_profile)
Scenario:
Given my locale is "de"
And I am logged in as a normal user
When I go to the home page
And I follow t(profile)
Then I should see t(your_profile)
This, too, is easy to support. We can add the following step to our locale steps:
# features/step_definitions/locale_steps.rb
Given /^my locale is "([^"]*)"$/ do |locale|
I18n.locale = locale
end
And then add some cleanup code into our support files, to prevent the locale from one scenario bleeding into the others.
# features/support/locale.rb
After do
I18n.locale = I18n.default_locale
end
Step 3: Use scenario outlines
We could stop there.. but we’re not done yet! We certainly don’t want to duplicate (or triplicate, or…) all of our scenarios, so let’s use a scenario outline to clean this up:
Feature: User views profile
Scenario Outline:
Given my locale is "<locale>"
And I am logged in as a normal user
When I go to the home page
And I follow t(profile)
Then I should see t(your_profile)
Examples:
| locale |
| en |
| de |
And there we go! Now we’ve verified that our UI works in both English and German, with just a handful of new step definitions. Happy cuking!