Salatalık adımlarını yeniden kullanın


103

Bazı Salatalık adımlarını yeniden kullanmak istiyorum ama doğru yolu bulamıyorum.

Şöyle bir adım yazmak istiyorum:

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

Ama sonra şöyle bir adım daha at:

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

Bu yüzden kullanıcı kimlik doğrulamasını test ederken ilkini kullanabilirim, ancak diğer birçok yerde ikincisini kullanabilirim ve aslında kodu yeniden üretmem gerekmiyor.

Bu diğer adımı çağırmanın bir yolu var mı, yoksa mantığı bir yardımcı yönteme mi koyuyorum ve her görevden adı geçen yöntemi çağırıyorum (temelde bir yöntem çıkarma yeniden düzenleme, ki bu, sorumu okuduktan sonra bunun aslında en iyi yol olduğuna inanmamı sağlıyor. neyse)?


1
Herhangi birinin kafası karışmışsa, buradaki herkes bloğu Ruby adım tanımında dobaşlatmak için gerekli olanı dışarıda bırakıyor do...end. Aslında gereklidir.
Shaun Lebron

Yanıtlar:


102

GÜNCELLEME : Aşağıda açıklanan yöntem kullanımdan kaldırılmıştır. Başka bir adımdan bir adımı çağırmanın önerilen yolu artık şuna benzer:

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

Eski, kullanımdan kaldırılmış yöntem (referans için):

Aşağıdaki gibi diğer adımlardan adımları çağırabilirsiniz:

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

Bir özellikteki tüm senaryolar bunu (veya diğer adımları) gerektiriyorsa, aşağıdaki gibi genel adımlarla her özelliğe bir Arka Plan da ekleyebilirsiniz:

Background:
  Given I log in with valid credentials

Scenario: Change my password
  Given I am on the account page

5
Kornişon kodunu şu şekilde yapıştırmak daha da kolay:steps %Q{Given I am logged in}
BrendanDean

1
@BrendanDean Bu cevap kabul edildiğinde stepsyöntem yoktu. Aşağıdaki cevabıma bakın.
michaeltwofish

Lütfen birleşik adımların artık bir anti-model olarak kabul edildiğini ve bundan kaçınılması gerektiğini unutmayın. Cucumber wiki'sini görün - cucumber.io/docs/guides/anti-patterns/…
Jan Molak

103

Adımlar içindeki adımları çağırma yönteminin son salatalığın sürümlerinde değiştiğine dikkat edin; "UYARI: Adım tanımlarında 'Verildi / Ne Zaman / Sonra' gibi bir hata alırsanız göremezsiniz, için 'adım' kullanın. bunun yerine diğer adımları çağırın: /path/to/step_definitions/foo_steps.rb: 631: "blok içinde '". Ayrıntılar için salatalık wiki'sine bakın.

Değişikliğin özü, şimdi stepveya stepsyöntemlerini kullanmanız gerektiğidir .

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
Değeri ne olursa olsun, Salatalık ile daha fazla zaman geçirdikten sonra, adım adımlarını hiç kullanmamanızı tavsiye ederim. Sorunların izini sürmek zordur ve aslında bakımı zorlaştırır. Bunun yerine yardımcı yöntemler kullanın.
michaeltwofish

2
Belki de, çok olumlu oy verildiği ve hala oy aldığı için bu yorumu cevabınıza eklemelisiniz. İnsanların bu bilgiyi fark etmelerine yardımcı olacak
Andrei Botalov

merhaba @michaeltwofish, 2017'de bunda herhangi bir değişiklik var mı? syntax error, unexpected tIDENTIFIER, expecting keyword_end Stackoverflow.com/questions/43319331/…
ericn

43

Adım tanımlarından adım çağırmak kötü bir uygulamadır ve bazı dezavantajları vardır :

  1. Senaryo başarısız olursa ve iç içe adım çağrıları varsa, yığın izlemede yalnızca son çağrılan adım tanımını alırsınız. Son step definin hangi yerden çağrıldığını bulmak zor olabilir
  2. Stepdef çağrısı bazen Ruby yönteminden daha zor bulunur ve okunur
  3. Ruby yöntemleri size defs adımlarından adım çağırmaktan daha fazla güç sağlar

Aslak Hellesøy önerir popüler eylemleri ayıklamak için Dünya yerine adımları tekrar kullanmanın. Bu eylemleri tek bir yerde izole eder ve bu kodun bulunmasını kolaylaştırır. Kodu normal Ruby sınıflarına veya modüllerine de çıkarabilirsiniz.

#/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

İşte Salatalık posta listesindeki konuyla ilgili yararlı bir tartışma - bağlantı


2
Bu yaklaşımın, yukarıda belirtilen nedenlerle adım veya adım işlevlerini çağırmaktan çok daha iyi olduğuna inanıyorum.
pisaruk

2
Bunun başka bir faydası daha var. Fikir (veya Rubymine) kullanarak, kolayca işlev tanımlarına atlayabilirsiniz, ancak% {...} adımlarındaki adımlara atlayamazsınız.
2012'de

bu kurulum da KURU prensibini izler
Sorcerer86pt

2
Adımları yeniden kullanma sorununa denk gelmeme rağmen, bunun kötü olduğunu düşünüyorum. Giriş, farklı adımların toplamıdır: "bir şeyi ziyaret edin", "bir şeyi doldurun". Doğal yol, her adımı bir işlev çağrısına dönüştürmek yerine yeniden kullanım adımları olacaktır. IMO, adımların içindeki adımları çağırmak sadece iyileştirilmelidir.
dgmora

9

En iyisi adımlarınızı tırnak işareti yerine% {} ile sarın. Ardından, sık sık kullanmanız gereken çift tırnak işaretlerinden kaçmanıza gerek kalmaz:

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
Bu bir cevap yerine bir yorum olmalıydı.
Kelvin

1

Anahtar kelimeleri, kodun yeniden kullanılabilirliğini sağlayacak özellik dosyasında yeniden kullanın.

Adım tanımları içinde adım deflerinin çağrılması kesinlikle ÖNERİLMEZ.

Özellik dosyamı bu şekilde yazardım,

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       |

Adım tanımımda, (Bu Java'dır)

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

Bu şekilde, çok fazla kod yeniden kullanılabilirliği vardır. Aynı Verilen ve Sonra hem geçerli hem de geçersiz senaryoları işler. Aynı zamanda, özellik dosyanız okuyucular için anlamlıdır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.