Статьи

Простая интернационализация для вашего Rails приложения с BDD

У моей компании есть веб-приложение в формате США, которое мы изменили для использования нашим филиалом в Великобритании. Тем не менее, наша текущая потребность изменить его и добавить некоторые функции ведет нас по пути полного переписывания. Но я верю, что Rails спас день. Я собираюсь показать вам, как легко «интернационализировать» с помощью Rails. Это будет первая в серии дальнейшие тесты для создания, чтения, использования и удаления (CRUD).

Мы начнем с создания приложения на Rails. Мне нравится использовать Cucumber и factory_girl для тестирования, поэтому нам не понадобится тестовый модуль.

$ rails new international --skip-test-unit
...
$ cd international
international $

Откройте папку с нашим новым приложением и отредактируйте Gemfile. Нам нужно добавить Gems тестирования к нему.

 group :test do
  gem 'cucumber-rails', '1.2.1'
  gem 'rspec-rails', '2.8.1'
  gem 'database<em>cleaner', '0.7.1'
 gem 'factory</em>girl', '2.4.0'
end

Сохраните файл. Теперь запустите bundler, чтобы установить новые гемы.

 international $ bundle install
Fetching source index for http://rubygems.org/
Using rake (0.9.2.2)
Using multi<em>json (1.0.4)
Using activesupport (3.1.3)
Using builder (3.0.0)
Using i18n (0.6.0)
Using activemodel (3.1.3)
Using erubis (2.7.0)
Using rack (1.3.6)
Using rack-cache (1.1)
Using rack-mount (0.8.3)
Using rack-test (0.6.1)
Using hike (1.2.1)
Using tilt (1.3.3)
Using sprockets (2.0.3)
Using actionpack (3.1.3)
Using mime-types (1.17.2)
Using polyglot (0.3.3)
Using treetop (1.4.10)
Using mail (2.3.0)
Using actionmailer (3.1.3)
Using arel (2.2.1)
Using tzinfo (0.3.31)
Using activerecord (3.1.3)
Using activeresource (3.1.3)
Using bundler (1.0.21)
Installing nokogiri (1.5.0) with native extensions
Installing ffi (1.0.11) with native extensions
Installing childprocess (0.3.0)
Installing rubyzip (0.9.5)
Installing selenium-webdriver (2.17.0)
Installing xpath (0.1.4)
Installing capybara (1.1.2)
Using coffee-script-source (1.2.0)
Using execjs (1.2.13)
Using coffee-script (2.2.0)
Using rack-ssl (1.3.2)
Using json (1.6.5)
Using rdoc (3.12)
Using thor (0.14.6)
Using railties (3.1.3)
Using coffee-rails (3.1.1)
Installing diff-lcs (1.1.3)
Installing gherkin (2.7.3) with native extensions
Installing term-ansicolor (1.0.7)
Installing cucumber (1.1.4)
Installing cucumber-rails (1.2.1)
Installing database</em>cleaner (0.7.1)
Installing factory_girl (2.4.0)
Using jquery-rails (1.0.19)
Using rails (3.1.3)
Installing rspec-core (2.8.0)
Installing rspec-expectations (2.8.0)
Installing rspec-mocks (2.8.0)
Installing rspec (2.8.0)
Installing rspec-rails (2.8.1)
Using sass (3.1.12)
Using sass-rails (3.1.5)
Using sqlite3 (1.3.5)
Using uglifier (1.2.2)
Your bundle is complete! Use <code>bundle show [gemname]</code> to see where a bundled gem is installed.

С новыми загруженными драгоценными камнями мы можем установить Огурец.

 international $ rails generate cucumber:install
create config/cucumber.yml
create script/cucumber
 chmod script/cucumber
create features/step_definitions
create features/support
create features/support/env.rb
 exist lib/tasks
create lib/tasks/cucumber.rake
  gsub config/database.yml
  gsub config/database.yml
 force config/database.yml

Чтобы огурец работал, нам нужно создать базу данных, хотя у нас нет моделей. Следующая команда сделает это:

 international $ rake db:migrate db:test:prepare

Посмотрим, работает ли это. Иди вперед и беги огурец

 international $ cucumber
Using the default profile...
0 scenarios
0 steps
0m0.000s

Оно работает.

Теперь мы можем создать наш первый тест. Создайте новый файл в папке функций с именем manage_locations.feature

 Feature: Manage locations
  In order to manage locations
  As a user
  I want to create and edit my locations.
  Scenario: List a location.
    Given there is a location named "location 1"
    When I am on the locations page
    Then I should see "location 1"

Сохраните файл и давайте запустим тест.

 international $ cucumber
  Using the default profile...
  Feature: Manage locations
  In order to manage locations
  As a user
  I want to create and edit my locations.
  Scenario: List a location. # features/manage<em>locations.feature:6
 Given there is a location named "location 1" # features/manage</em>locations.feature:7
      Undefined step: "there is a location named "location 1"" (Cucumber::Undefined)
      features/manage<em>locations.feature:7:in <code>Given there is a location named "location 1"'
 When I am on the locations page # features/manage_locations.feature:8
 Undefined step: "I am on the locations page" (Cucumber::Undefined)
 features/manage_locations.feature:8:in</code>When I am on the locations page'
 Then I should see "location 1" # features/manage</em>locations.feature:9
      Undefined step: "I should see "location 1"" (Cucumber::Undefined)
      features/manage_locations.feature:9:in `Then I should see "location 1"'
  1 scenario (1 undefined)
  3 steps (3 undefined)
  0m1.745s
You can implement step definitions for undefined steps with these snippets:
Given /^there is a location named "([^"]<em>)"$/ do |arg1|
 pending # express the regexp above with the code you wish you had
end
When /^I am on the locations page$/ do
 pending # express the regexp above with the code you wish you had
end
Then /^I should see "([^"]</em>)"$/ do |arg1|
 pending # express the regexp above with the code you wish you had
end

Как говорит Cucumber, мы реализуем шаги, используя шаблон, который он нам дал.

Создайте новый файл в папке / features / step_definitions с именем location_steps.rb. Скопируйте и вставьте эти фрагменты в только что созданный файл.

 Given /^there is a location named "([^"]<em>)"$/ do |arg1|
 pending # express the regexp above with the code you wish you had
end
When /^I am on the locations page$/ do
 pending # express the regexp above with the code you wish you had
end
Then /^I should see "([^"]</em>)"$/ do |arg1|
  pending # express the regexp above with the code you wish you had
end

Давайте сохраним файл и снова запустим тест.

 international $ cucumber
  Using the default profile...
  Feature: Manage locations
  In order to manage locations
  As a user
  I want to create and edit my locations.
  Scenario: List a location. # features/manage<em>locations.feature:6
 Given there is a location named "location 1" # features/step</em>definitions/location<em>steps.rb:1
 TODO (Cucumber::Pending)
 ./features/step</em>definitions/location<em>steps.rb:2:in <code>/^there is a location named "([^"]*)"$/'
 features/manage_locations.feature:7:in</code>Given there is a location named "location 1"'
 When I am on the locations page # features/step</em>definitions/location<em>steps.rb:5
 Then I should see "location 1" # features/step</em>definitions/location_steps.rb:9
  1 scenario (1 pending)
  3 steps (2 skipped, 1 pending)
  0m1.249s

Как и ожидалось, он не проходит, но там немного меньше шума. Нам нужно создать модель местоположения, чтобы мы могли иметь местоположения. Используя генератор, создайте его, и на данный момент у него будет только атрибут name.

 international $ rails g model location name:string
invoke active<em>record
create db/migrate/20120118214355</em>create_locations.rb
create   app/models/location.rb

Создав модель, пора запустить миграцию и подготовить тестовую базу данных.

 international $ rake db:migrate db:test:prepare
==  CreateLocations: migrating ================================================
-- create_table(:locations)
   -> 0.0015s
==  CreateLocations: migrated (0.0016s) =======================================

Теперь мы можем создать местоположение.

Мне нравится использовать factory_girl. Это позволяет легко создавать тестовые данные. ( Узнайте больше ) Это займет немного времени, но я думаю, что оно того стоит.

В папке / features / support создайте файл factories.rb и добавьте следующее.

 require 'factory_girl'
FactoryGirl.define do
  factory :location do |f|
    f.name 'test location'
  end
end

Это создаст местоположение с именем «тестовое местоположение» в базе данных для целей тестирования. Вы всегда можете передать имя фабрике, так что это не обязательно будет «тестовое местоположение». Мы скоро увидим пример этого.

В файле location_steps.rb измените первый шаг, чтобы он выглядел следующим образом:

 Given /^there is a location named "([^"]*)"$/ do |name|
  Factory(:location, :name => name)
end

Сохраните файл и повторите тест

 international $ cucumber
  Using the default profile...
  Feature: Manage locations
  In order to manage locations
  As a user
  I want to create and edit my locations.
  Scenario: List a location. # features/manage<em>locations.feature:6
 Given there is a location named "location 1" # features/step</em>definitions/location<em>steps.rb:1
 When I am on the locations page # features/step</em>definitions/location<em>steps.rb:5
 TODO (Cucumber::Pending)
 ./features/step</em>definitions/location<em>steps.rb:6:in <code>/^I am on the locations page$/'
 features/manage_locations.feature:8:in</code>When I am on the locations page'
 Then I should see "location 1" # features/step</em>definitions/location_steps.rb:9
  1 scenario (1 pending)
  3 steps (1 skipped, 1 pending, 1 passed)
  0m1.485s

Отлично … первый шаг проходит.

Далее мы перейдем на страницу местоположений, но нам нужно будет составить маршрут для этого.

Откройте файл route.rb в папке config и добавьте

 match 'locations/' => 'locations#index', :as => :locations

Это приведет нас к странице индекса местоположений.
Мы можем проверить маршрут, набрав в командной строке:

 international $ rake routes
locations /locations(.:format) locations#index

в файле location_steps.rb давайте расскажем, куда идти, добавив:

 When /^I am on the locations page$/ do
  visit(locations_path)
end

Сохраните файл и повторите тест.

 international $ cucumber
  Using the default profile...
  Feature: Manage locations
  In order to manage locations
  As a user
  I want to create and edit my locations.
  Scenario: List a location. # features/manage<em>locations.feature:6
 Given there is a location named "location 1" # features/step</em>definitions/location<em>steps.rb:1
 When I am on the locations page # features/step</em>definitions/location<em>steps.rb:5
uninitialized constant LocationController (ActionController::RoutingError)
 ./features/step</em>definitions/location<em>steps.rb:6:in <code>/^I am on the locations page$/'
 features/manage_locations.feature:8:in</code>When I am on the locations page'
 Then I should see "location 1" # features/step</em>definitions/location<em>steps.rb:9
 Failing Scenarios:
 cucumber features/manage</em>locations.feature:6 # Scenario: List a location.
  1 scenario (1 failed)
  3 steps (1 failed, 1 skipped, 1 passed)
  0m1.501s

Это говорит нам, что нет LocationsController.
Хорошо, создайте его и просто позаботьтесь о странице индекса.

 international $ rails g controller locations index
 create app/controllers/locations<em>controller.rb
 route get "locations/index"
 invoke erb
 create app/views/locations
 create app/views/locations/index.html.erb
 invoke helper
 create app/helpers/locations</em>helper.rb
 invoke assets
 invoke   coffee
 create     app/assets/javascripts/locations.js.coffee
 invoke   scss
 create     app/assets/stylesheets/locations.css.scss

Давайте перейдем в файл маршрутов (config / rout.rb) и удалим маршрут, который был создан, когда мы создали контроллер.

Удалить эту строку.

 get "locations/index"

Сохраните файл. Теперь, когда у нас есть контроллер, давайте снова запустим тест.

 international $ cucumber
  Using the default profile...
  Feature: Manage locations
  In order to manage locations
  As a user
  I want to create and edit my locations.
  Scenario: List a location. # features/manage<em>locations.feature:6
 Given there is a location named "location 1" # features/step</em>definitions/location<em>steps.rb:1
 When I am on the locations page # features/step</em>definitions/location<em>steps.rb:5
 Then I should see "location 1" # features/step</em>definitions/location<em>steps.rb:9
 TODO (Cucumber::Pending)
 ./features/step</em>definitions/location_steps.rb:10:in <code>/^I should see "([^"]*)"$/'
 features/manage_locations.feature:9:in</code>Then I should see "location 1"'
  1 scenario (1 pending)
  3 steps (1 pending, 2 passed)
  0m1.858s

Отлично. Нам просто нужно отобразить названия мест. В папке / app / views / location откройте файл index.html.erb. Мы добавим этот код, который будет перебирать имена:

 <ul>
  <% @locations.each do |location| %>
    <li>
      <%= location.name %>
    </li>
  <% end %>
</ul>

Давайте посмотрим, что произойдет, если мы запустим тест сейчас.

 international $ cucumber
  Using the default profile...
  Feature: Manage locations
  In order to manage locations
  As a user
  I want to create and edit my locations.
  Scenario: List a location. # features/manage<em>locations.feature:6
 Given there is a location named "location 1" # features/step</em>definitions/location<em>steps.rb:1
 When I am on the locations page # features/step</em>definitions/location<em>steps.rb:5
 You have a nil object when you didn't expect it!
 You might have expected an instance of Array.
 The error occurred while evaluating nil.each (ActionView::Template::Error)
 ......
 features/manage</em>locations.feature:8:in `When I am on the locations page'
    Then I should see "location 1" # features/step<em>definitions/location</em>steps.rb:9
Failing Scenarios:
cucumber features/manage_locations.feature:6 # Scenario: List a location.
1 scenario (1 failed)
3 steps (1 failed, 1 skipped, 1 passed)
0m1.599s

Ноль объект? Мы ничего не получили из базы данных. Давайте исправим это, открыв файл location_controller.rb в / app / controllers. Измените метод index:

 def index
  @locations = Location.all

  respond_to do |format|
    format.html # index.html.erb
    format.json { render json: @locations }
  end
end

В location_step.rb нам нужно изменить следующее:

 Then /^I should see "([^"]*)"$/ do |arg1|
  pending # express the regexp above with the code you wish you had
end

чтобы:

 Then /^(?:|I )should see "([^"]*)"$/ do |text|
  if page.respond_to? :should
    page.should have_content(text)
  else
    assert page.has_content?(text)
  end
end

Сохраните файлы и перезапустите тест.

 international $ cucumber
  Using the default profile...
  Feature: Manage locations
  In order to manage locations
  As a user
  I want to create and edit my locations.
  Scenario: List a location. # features/manage<em>locations.feature:6
 Given there is a location named "location 1" # features/step</em>definitions/location<em>steps.rb:1
 When I am on the locations page # features/step</em>definitions/location<em>steps.rb:5
 Then I should see "location 1" # features/step</em>definitions/location_steps.rb:9
  1 scenario (1 passed)
  3 steps (3 passed)
  0m1.679s

Ладно, все зеленые! Первый тест проходит!
Кому нужен перерыв?

¿Хабла испанский?

Давайте перейдем к интернационализации. Нам нужно сделать модуль i18n. В папке / config / initializers / создайте новый файл с именем i18n.rb
В этом файле мы добавим

 #encoding: utf-8

I18n.default_locale = :en

LANGUAGES = [
  ['English', 'en'],
  ["Español".html_safe, 'es']
]

Это устанавливает язык по умолчанию на английский и создает список языков, которые мы будем поддерживать вместе с их локалями.
Локаль будет указана в URL, сообщая нам, какой язык использовать. Мы добавим это в маршруты и добавим корневой URL. Не забудьте удалить /public/index.html!

Откройте файл rout.Rb и добавьте следующие строки:

 scope '(:locale)' do
  match 'locations/' => 'locations#index', :as => :locations
  root :to => 'locations#index'
end

Мы вложили наши маршруты в область видимости: locale, и поскольку она в скобках, она необязательна.

http: // localhost: 3000 / es будет использовать локаль по умолчанию, английский. http: // localhost: 3000 / en и http: // localhost: 3000 / es будут использовать тот же контроллер и метод, но будут использовать указанную локаль в URL

Теперь нам нужно установить локаль на основе параметра в URL, если он указан.

Мы сделаем это в Application Controller с фильтром before. Откройте файл application_colbtroller.rb в папке / app / controllers.

Добавьте эту строку:

 class ApplicationController < ActionController::Base
  before_filter :set</em>i18n<em>locale_from_params
  protect_from_forgery

protected
  def set_i18n_locale_from_params
    if params[:locale]
      if I18n.available_locales.include?(params[:locale].to_sym)
        I18n.locale = params[:locale]
      else
        flash.now[:notice] = "#{params[:locale]} translation not available"
        logger.error
        flash.now[:notice]
      end
    end
  end
  def default_url_options
    { locale: I18n.locale }
  end
end

Так что здесь он проверяет параметр локали. Если он есть, он проверяет, присутствует ли этот языковой стандарт в нашем списке языков в файле /config/initializers/i18n.rb. Если он есть в списке, мы устанавливаем локаль для параметра. Если его нет в списке, мы покажем сообщение о том, что локаль недоступна.

Default_url_options устанавливает язык по умолчанию, если он не указан. Поскольку в этот момент мы внесли много изменений, давайте сохраним все файлы и повторно запустим тест.

 international $ cucumber

Using the default profile...
Feature: Manage locations
In order to manage locations
As a user
I want to create and edit my locations.

Scenario: List a location. # features/manage<em>locations.feature:6
Given there is a location named "location 1" # features/step</em>definitions/location<em>steps.rb:1
When I am on the locations page # features/step</em>definitions/location<em>steps.rb:5
Then I should see "location 1" # features/step</em>definitions/location_steps.rb:9

1 scenario (1 passed)
3 steps (3 passed)
0m1.583s

Все еще зеленый. Уф.
Давайте приготовим это.
На нашей странице указателей местоположений добавьте заголовок «Местоположения»

Откройте файл manage_locations.feature и добавьте

 Scenario: List a location.
Given there is a location named "location 1"
When I am on the locations page
Then I should see "Locations"
And I should see "location 1"

Сохраните файлы и перезапустите тест.

 international $ cucumber
  Using the default profile...
  Feature: Manage locations
  In order to manage locations
  As a user
  I want to create and edit my locations.
  Scenario: List a location. # features/manage<em>locations.feature:6
 Given there is a location named "location 1" # features/step</em>definitions/location<em>steps.rb:1
 When I am on the locations page # features/step</em>definitions/location<em>steps.rb:5
 Then I should see "Locations" # features/step</em>definitions/location<em>steps.rb:9
 expected there to be content "Locations" in "Internationalnnnn location 1n n" (RSpec::Expectations::ExpectationNotMetError)
 ./features/step</em>definitions/location<em>steps.rb:11:in <code>/^(?:|I )should see "([^"]*)"$/'
 features/manage_locations.feature:9:in</code>Then I should see "Locations"'
 And I should see "location 1" # features/step</em>definitions/location<em>steps.rb:9
 Failing Scenarios:
 cucumber features/manage</em>locations.feature:6 # Scenario: List a location.
  1 scenario (1 failed)
  4 steps (1 failed, 1 skipped, 2 passed)
  0m1.593s

Сбой, как и ожидалось.

Откройте файл index.html.ern в / app / views / location и добавьте

 <h1>Locations</h1>

Сохраните файл и повторите тест.

 international $ cucumber
  Using the default profile...
  Feature: Manage locations
  In order to manage locations
  As a user
  I want to create and edit my locations.
  Scenario: List a location. # features/manage<em>locations.feature:6
 Given there is a location named "location 1" # features/step</em>definitions/location<em>steps.rb:1
 When I am on the locations page # features/step</em>definitions/location<em>steps.rb:5
 Then I should see "Locations" # features/step</em>definitions/location<em>steps.rb:9
 And I should see "location 1" # features/step</em>definitions/location_steps.rb:9
  1 scenario (1 passed)
  4 steps (4 passed)
  0m1.604s

Мы вернулись к зеленому.

Теперь скопируйте тот же тест, но вместо «Location» в заголовке мы должны увидеть «Locaciones»
Измените ваш manage_locations.feature на:

 Feature: Manage locations
  In order to manage locations
  As a user
  I want to create and edit my locations.
  Scenario: List a location.
    Given there is a location named "location 1"
    When I am on the locations page
    Then I should see "Locations"
    And I should see "location 1"
  Scenario: List a location.
    Given there is a location named "location 1"
    When I am on the locations page
    Then I should see "Locaciones"
    And I should see "location 1"

Сохраните файл и повторите тест

 international $ cucumber
  Using the default profile...
  Feature: Manage locations
  In order to manage locations
  As a user
  I want to create and edit my locations.
  Scenario: List a location. # features/manage<em>locations.feature:6
 Given there is a location named "location 1" # features/step</em>definitions/location<em>steps.rb:1
 When I am on the locations page # features/step</em>definitions/location<em>steps.rb:5
 Then I should see "Locations" # features/step</em>definitions/location<em>steps.rb:9
 And I should see "location 1" # features/step</em>definitions/location<em>steps.rb:9
 Scenario: List a location. # features/manage</em>locations.feature:12
    Given there is a location named "location 1" # features/step<em>definitions/location</em>steps.rb:1
    When I am on the locations page # features/step<em>definitions/location</em>steps.rb:5
    Then I should see "Locaciones" # features/step<em>definitions/location</em>steps.rb:9
     expected there to be content "Locaciones" in "InternationalnnLocationsnnn location 1n n" (RSpec::Expectations::ExpectationNotMetError)
     ./features/step<em>definitions/location</em>steps.rb:11:in <code>/^(?:|I )should see "([^"]*)"$/'
features/manage_locations.feature:15:in</code>Then I should see "Locaciones"'
    And I should see "location 1" # features/step<em>definitions/location</em>steps.rb:9
  Failing Scenarios:
  cucumber features/manage_locations.feature:12 # Scenario: List a location.
  2 scenarios (1 failed, 1 passed)
  8 steps (1 failed, 1 skipped, 6 passed)
  0m1.643s

Это не удалось, где мы ожидали.
Вот где окупается весь код, который мы делали ранее. Время переводить. Для слов, которые нам нужно перевести, мы назовем I18n.translate с псевдонимом I18n.t. Также есть помощник с именем t.
Параметром функции перевода является уникальное имя с точечной точкой. Мы можем выбрать любое имя, которое вам нравится, но если мы используем предоставленную вспомогательную функцию t, имена, начинающиеся с точки, будут сначала расширяться с использованием имени шаблона. Давайте сделаем это.

В index.html.erb измените его следующим образом

 <h1>Locations</h1>

в

 <h1><%= t('.title_html') %></h1>

Сохраните файл.
Нам нужно создать файл en.yml в папке / config / locales.

 en:

locations:
    index:
      title_html:    "Locations

Нам также нужно создать файл es.yml в папке / config / locales

 es:

locations:
    index:
      title_html:    "Locaciones"

Эти файлы содержат переводы. Также обратите внимание на структуру YAML напоминает структуру файла? (/ Местоположение / индекс). Это будет удобно в будущем.
Сохраните файлы и повторите тест… снова.

 international $ cucumber
  Using the default profile...
  Feature: Manage locations
  In order to manage locations
  As a user
  I want to create and edit my locations.
  Scenario: List a location. # features/manage<em>locations.feature:6
 Given there is a location named "location 1" # features/step</em>definitions/location<em>steps.rb:1
 When I am on the locations page # features/step</em>definitions/location<em>steps.rb:5
 Then I should see "Locations" # features/step</em>definitions/location<em>steps.rb:9
 And I should see "location 1" # features/step</em>definitions/location<em>steps.rb:9
 Scenario: List a location. # features/manage</em>locations.feature:12
    Given there is a location named "location 1" # features/step<em>definitions/location</em>steps.rb:1
    When I am on the locations page # features/step<em>definitions/location</em>steps.rb:5
    Then I should see "Locaciones" # features/step<em>definitions/location</em>steps.rb:9
     expected there to be content "Locaciones" in "InternationalnnLocationsnnn location 1n n" (RSpec::Expectations::ExpectationNotMetError)
     ./features/step<em>definitions/location</em>steps.rb:11:in <code>/^(?:|I )should see "([^"]*)"$/'
 features/manage_locations.feature:15:in</code>Then I should see "Locaciones"'
    And I should see "location 1" # features/step<em>definitions/location</em>steps.rb:9
  Failing Scenarios:
  cucumber features/manage_locations.feature:12 # Scenario: List a location.
  2 scenarios (1 failed, 1 passed)
  8 steps (1 failed, 1 skipped, 6 passed)
  0m1.643s

ЧТО? Красный?
Кажется, что во втором тесте мы никогда не говорили использовать es в качестве локали, поэтому по умолчанию используется en .

Давайте исправим это следующим образом:

 Scenario: List a location.
  Given there is a location named "location 1"
  And I am on the es site
  When I am on the locations page
  Then I should see "Locaciones"
  And I should see "location 1"

Сохраните файлы и перезапустите тест.

 international $ cucumber
  Using the default profile...
  Feature: Manage locations
  In order to manage locations
  As a user
  I want to create and edit my locations.
  Scenario: List a location. # features/manage<em>locations.feature:6
 Given there is a location named "location 1" # features/step</em>definitions/location<em>steps.rb:1
 When I am on the locations page # features/step</em>definitions/location<em>steps.rb:5
 Then I should see "Locations" # features/step</em>definitions/location<em>steps.rb:9
 And I should see "location 1" # features/step</em>definitions/location<em>steps.rb:9
 Scenario: List a location. # features/manage</em>locations.feature:12
    Given there is a location named "location 1" # features/step<em>definitions/location</em>steps.rb:1
    And I am on the es site # features/manage<em>locations.feature:14
 Undefined step: "I am on the es site" (Cucumber::Undefined)
 features/manage</em>locations.feature:14:in `And I am on the es site'
    When I am on the locations page # features/step<em>definitions/location</em>steps.rb:5
    Then I should see "Locaciones" # features/step<em>definitions/location</em>steps.rb:9
    And I should see "location 1" # features/step<em>definitions/location</em>steps.rb:9
  2 scenarios (1 undefined, 1 passed)
  9 steps (3 skipped, 1 undefined, 5 passed)
  0m1.723s
  You can implement step definitions for undefined steps with these snippets:
  Given /^I am on the es site$/ do
    pending # express the regexp above with the code you wish you had
  end

Ладно! Это говорит нам, что делать.
Откройте файл location_steps.rb и добавьте его в него.

 Given /^I am on the (.+) site$/ do |language|
  I18n.locale = language
end

Сохраните файл и повторите тест.

 international $ cucumber
  Using the default profile...
  Feature: Manage locations
  In order to manage locations
  As a user
  I want to create and edit my locations.
  Scenario: List a location. # features/manage<em>locations.feature:6
 Given there is a location named "location 1" # features/step</em>definitions/location<em>steps.rb:1
 When I am on the locations page # features/step</em>definitions/location<em>steps.rb:5
 Then I should see "Locations" # features/step</em>definitions/location<em>steps.rb:9
 And I should see "location 1" # features/step</em>definitions/location<em>steps.rb:9
 Scenario: List a location. # features/manage</em>locations.feature:12
    Given there is a location named "location 1" # features/step<em>definitions/location</em>steps.rb:1
    And I am on the es site # features/step<em>definitions/location</em>steps.rb:17
    When I am on the locations page # features/step<em>definitions/location</em>steps.rb:5
    Then I should see "Locaciones" # features/step<em>definitions/location</em>steps.rb:9
    And I should see "location 1" # features/step<em>definitions/location</em>steps.rb:9
  2 scenarios (2 passed)
  9 steps (9 passed)
  0m1.636s

ГОЛ! Теперь у вас есть очень простой многоязычный сайт. Я надеюсь, что вы нашли полезным использовать BDD для интернационализации вашего Rails-приложения.