오이 단계 재사용


103

오이 단계를 재사용하고 싶지만 올바른 방법을 찾지 못하는 것 같습니다.

다음과 같은 단계를 작성하고 싶습니다.

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

따라서 사용자 인증을 테스트 할 때 전자를 사용할 수 있지만 대부분의 다른 곳에서는 후자를 사용할 수 있으며 실제로 코드를 재현 할 필요가 없습니다.

다른 단계를 호출하는 방법이 있습니까? 아니면 로직을 도우미 메서드에 넣고 각 작업에서 해당 메서드를 호출합니까 (기본적으로 메서드 추출 리팩토링, 내 질문을 읽은 후 실제로 이것이 가장 좋은 방법이라고 믿게 만듭니다) 어쨌든)?


1
누군가 혼란 스러울 경우, 여기있는 모든 사람들 은 Ruby 단계 정의에서 블록 do을 시작하는 데 필요한 부분을 생략합니다 do...end. 실제로 필요합니다.
Shaun Lebron 2014 년

답변:


102

업데이트 : 아래에 설명 된 방법은 더 이상 사용되지 않습니다. 이제 다른 단계에서 단계를 호출하는 권장 방법은 다음과 같습니다.

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

5
더 쉬운 방법은 작은 오이 코드를 다음과 같이 붙여 넣는 것입니다.steps %Q{Given I am logged in}
BrendanDean 2011-08-09

1
@BrendanDean이 답변이 받아 들여졌을 때 그 steps방법은 존재하지 않았습니다. 아래 내 대답을 참조하십시오.
michaeltwofish

접속 단계는 이제 안티 패턴으로 간주되므로 피해야합니다. - 오이 위키 참조 cucumber.io/docs/guides/anti-patterns/...
월 Molak

103

단계 내에서 단계를 호출하는 방법이 최근 버전의 오이에서 변경되었습니다. "경고 : 단계 정의에서 'Given / When / Then'사용이 더 이상 사용되지 않습니다. '단계'를 사용하여 다음과 같은 오류가 발생하면 확인할 수 있습니다. 대신 다른 단계를 호출하십시오 : /path/to/step_definitions/foo_steps.rb:631:in`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

18
그만한 가치를 위해, 오이와 더 많은 시간을 보낸 후에는 단계 내에서 단계를 전혀 사용하지 않는 것이 좋습니다. 문제는 추적하기 어렵고 실제로 유지 관리를 어렵게 만듭니다. 대신 도우미 메서드를 사용하십시오.
michaeltwofish

2
이 댓글은 매우 찬성되고 여전히 투표를 받기 때문에 답변에 포함해야 할 수도 있습니다. 그것은이 정보를 알 사람들을 도움이 될 것입니다
안드레이 Botalov에게

안녕하세요 @michaeltwofish 님, 2017 년에 변경 사항이 있습니까? 나는 syntax error, unexpected tIDENTIFIER, expecting keyword_end stackoverflow.com/questions/43319331/를
ericn

43

단계 정의에서 단계를 호출하는 것은 나쁜 습관이며 몇 가지 단점이 있습니다 .

  1. 시나리오가 실패하고 중첩 된 단계 호출이있는 경우 스택 추적에서 마지막으로 호출 된 단계 정의 만 가져옵니다. 마지막 stepdef가 어디에서 호출되었는지 찾기 어려울 수 있습니다.
  2. stepdef에 대한 호출은 때때로 루비 메소드보다 찾고 읽기가 더 어렵습니다.
  3. Ruby 메서드는 단계 정의에서 단계를 호출하는 것보다 더 많은 기능을 제공합니다.

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 메일 링리스트의 주제에 대한 유용한 토론입니다- 링크


2
이 접근 방식이 위에서 언급 한 것과 같은 이유로 단계 또는 단계 함수를 호출하는 것보다 훨씬 낫다고 생각합니다.
pisaruk

2
이것은 또 다른 이점이 있습니다. Idea (또는 Rubymine)를 사용하면 함수 정의로 쉽게 이동할 수 있지만 % {...} 단계의 단계로 이동할 수는 없습니다.
슬립 셋

또한이 설정은 DRY 원칙을 따릅니다
Sorcerer86pt

2
단계를 재사용하는 문제에 부딪 혔지만 이것은 단지 나쁘다고 생각합니다. 로그인은 "뭔가 방문", "뭔가 채우기"와 같은 여러 단계의 합계 일뿐입니다. 자연스러운 방법은 각 단계를 함수 호출로 변환하는 대신 단계를 재사용하는 것입니다. IMO, 단계 내 호출 단계는 개선되어야합니다.
dgmora

9

단계를 따옴표 대신 % {}로 감싸는 것이 가장 좋습니다. 그러면 자주 사용해야하는 큰 따옴표를 이스케이프 할 필요가 없습니다. :

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

5
이것은 대답이 아닌 주석이어야합니다.
Kelvin

1

코드 재사용 성을 제공하는 기능 파일에서 키워드를 재사용합니다.

단계 정의 내에서 단계 정의를 호출하지 않는 것이 좋습니다.

이런 식으로 기능 파일을 작성합니다.

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
    }
}

이러한 방식으로 많은 코드 재사용이 가능합니다. 동일한 Given and Then은 유효하고 잘못된 시나리오를 모두 처리합니다. 동시에 기능 파일은 독자에게 의미가 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.