Повторное использование шагов огурца - PullRequest
100 голосов
/ 28 мая 2009

Я хочу использовать несколько шагов огурца, но не могу найти правильный путь.

Я хочу написать шаг вроде:

Given /^I login with (.*) credentials$/ |type|
  # do stuff with type being one of "invalid" or "valid"
end

Но тогда сделайте еще один шаг, например:

Given /^I login successfully$
  # call "Given I login with valid credentials"
end

Таким образом, при тестировании аутентификации пользователя я могу использовать первое, но в большинстве других мест я могу использовать второе, и на самом деле не нужно повторять код.

Есть ли способ вызвать этот другой шаг, или я просто помещаю логику в вспомогательный метод и вызываю указанный метод из каждой задачи (в основном рефакторинг извлечения метода, который после прочтения моего вопроса заставляет меня поверить, что лучший путь в любом случае)?

Ответы [ 5 ]

102 голосов
/ 06 декабря 2011

Обратите внимание, что метод для вызова шагов в шагах изменился в последних версиях cucumber, что вы увидите, если получите сообщение об ошибке «ПРЕДУПРЕЖДЕНИЕ. Использование« Given / When / Then »в определениях шагов устарело, используйте step 'чтобы вызвать другие шаги вместо этого: /path/to/step_definitions/foo_steps.rb: 631: в `block in' "Подробнее см. огуречный вики .

Суть изменения заключается в том, что теперь вы должны использовать методы step или steps.

When /^I make all my stuff shiny$/
  step "I polish my first thing"
end

When /^I make all my stuff shiny$/
  steps %Q{
    When I polish my first thing
    When I shine my second thing
  }
end
101 голосов
/ 28 мая 2009

ОБНОВЛЕНИЕ : метод, описанный ниже, устарел. Рекомендуемый способ вызова шага из другого шага теперь выглядит следующим образом:

Given /^I login successfully$/
    step "I login with valid credentials" 
end 

Старый, устаревший метод (для справки):

Вы можете вызывать шаги из других шагов следующим образом:

Given /^I login successfully$/
  Given "I login with valid credentials"
  Then "I should be logged in"
end

Если все сценарии в рамках функции требуют этого (или других шагов), вы также можете добавить Фон для каждой функции, выполнив следующие общие шаги:

Background:
  Given I log in with valid credentials

Scenario: Change my password
  Given I am on the account page
42 голосов
/ 03 марта 2012

Вызов шагов из определений шагов является плохой практикой и имеет некоторые недостатки :

  1. Если сценарий не удастся выполнить и есть вложенные вызовы шагов, вы получите только последнее вызванное определение шага в трассировке стека. Может быть трудно найти, из какого места последний отчим был назван
  2. Призыв к stepdef иногда сложнее найти и прочитать, чем метод ruby ​​
  3. Методы Ruby дают вам больше возможностей, чем вызов шагов из step defs

Aslak Hellesøy рекомендует извлечь популярные действия в World вместо повторного использования шагов. Он изолирует эти действия в одном месте, облегчает поиск этого кода. Вы также можете извлекать код из обычных классов или модулей Ruby.

#/support/world_extensions.rb
module KnowsUser
  def login
    visit('/login')
    fill_in('User name', with: user.name)
    fill_in('Password', with: user.password)
    click_button('Log in')
  end

  def user
    @user ||= User.create!(:name => 'Aslak', :password => 'xyz')
  end
end
World(KnowsUser)

#/step_definitions/authentication_steps.rb
When /^I login$/ do
  login
end

Given /^a logged in user$/ do
  login
end

Вот полезная дискуссия на эту тему в списке рассылки Cucumber - ссылка

9 голосов
/ 21 февраля 2012

Лучше оберните ваши шаги в% {}, а не в кавычках. Тогда вам не нужно избегать двойных кавычек, которые вам нужно будет часто использовать.

Given /^I login successfully$
  step %{I login with valid credentials}
end

Given /^I login with (.*) credentials$/ |type|
  # do stuff with type being one of "invalid" or "valid"
end
1 голос
/ 31 мая 2013

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

Настоятельно НЕ рекомендуется вызывать пошаговые определения в пределах пошаговых определений.

Я бы написал свой файл функций таким образом,

Scenario Outline: To check login functionality
    Given I login with "<username>" and "<password>"
    Then I "<may or may not>" login successfully

Examples:
    |username|password|may or may not|
    |paul    |123$    |may           |
    |dave    |1111    |may not       |

В моем определении шага, (это Java)

@Given(I login with \"([^\"]*)\" and \"([^\"]*)\"$)
public void I_login_with_and(String username, String password){

   //login with username and password

}

@Then(I \"([^\"]*)\" login successfully$)
public void I_login_successully_if(String validity){

    if(validity.equals("may")){
        //assert for valid login
    }
    else
    if(validity.equals("may not")){
        //assert for invalid login
    }
}

Таким образом, много повторного использования кода. То же самое, что задано и затем обрабатывает как действительные, так и недействительные сценарии. В то же время, ваш файл функций имеет смысл для читателей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...