Gunakan kembali langkah Mentimun

103

Saya ingin menggunakan kembali beberapa langkah Ketimun tetapi sepertinya tidak dapat menemukan cara yang benar.

Saya ingin menulis langkah seperti:

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

Tapi kemudian lakukan langkah lain seperti:

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

Jadi dalam pengujian otentikasi pengguna saya dapat menggunakan yang pertama, tetapi di sebagian besar tempat lain, saya dapat menggunakan yang terakhir, dan sebenarnya tidak harus merepro kode.

Apakah ada cara untuk memanggil langkah lain itu, atau apakah saya hanya meletakkan logika dalam metode pembantu, dan memanggil metode tersebut dari setiap tugas (pada dasarnya metode ekstraksi refactoring, yang, setelah membaca pertanyaan saya membuat saya percaya bahwa itu sebenarnya cara terbaik bagaimanapun)?

Daniel Huckstep
sumber
1
Jika ada yang bingung, semua orang di sini tidak doperlu menjalankan do...endblok dalam definisi langkah Ruby. Itu sebenarnya dibutuhkan.
Shaun Lebron

Jawaban:

102

PEMBARUAN : Metode yang dijelaskan di bawah sudah tidak digunakan lagi. Cara yang disarankan untuk memanggil langkah dari dalam langkah lain sekarang terlihat seperti ini:

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

Metode lama dan tidak berlaku lagi (untuk referensi):

Anda dapat memanggil langkah-langkah dari langkah lain seperti ini:

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

Jika semua skenario dalam fitur memerlukan ini (atau langkah lain), Anda juga dapat menambahkan Latar Belakang ke setiap fitur, dengan langkah-langkah umum, seperti:

Background:
  Given I log in with valid credentials

Scenario: Change my password
  Given I am on the account page
tomafro.dll
sumber
5
Yang lebih mudah adalah menempelkan kode gherkin seperti ini:steps %Q{Given I am logged in}
BrendanDean
1
@BrendanDean Ketika jawaban ini diterima, stepsmetode tersebut tidak ada. Lihat jawaban saya di bawah.
michaeltwofish
Harap dicatat bahwa langkah penghubung sekarang dianggap sebagai anti-pola dan harus dihindari. Lihat wiki Ketimun - cucumber.io/docs/guides/anti-patterns/…
Jan Molak
103

Perhatikan bahwa metode untuk memanggil langkah-langkah dalam langkah-langkah telah berubah di versi terbaru ketimun, yang akan Anda lihat jika Anda mendapatkan kesalahan seperti "PERINGATAN: Menggunakan 'Diberikan / Kapan / Kemudian' dalam definisi langkah tidak berlaku lagi, gunakan 'langkah' untuk panggil langkah lain sebagai gantinya: /path/to/step_definitions/foo_steps.rb: 631: di `blokir '". Lihat wiki ketimun untuk detailnya.

Inti dari perubahannya adalah Anda sekarang harus menggunakan metode stepatau 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
michaeltwofish.dll
sumber
18
Untuk apa nilainya, setelah lebih banyak waktu dengan Mentimun, saya sarankan untuk tidak menggunakan langkah-langkah dalam langkah sama sekali. Masalah sulit dilacak dan sebenarnya membuat perawatan menjadi lebih sulit. Sebagai gantinya, gunakan metode pembantu.
michaeltwofish
2
Mungkin, Anda harus memasukkan komentar ini ke dalam jawaban Anda karena sangat disukai dan masih menerima suara. Ini akan membantu orang untuk memperhatikan informasi ini
Andrei Botalov
hai @michaeltwofish, apakah ada perubahan di tahun 2017 ini? Saya mendapatkan syntax error, unexpected tIDENTIFIER, expecting keyword_end stackoverflow.com/questions/43319331/…
ericn
43

Memanggil langkah-langkah dari definisi langkah adalah praktik yang buruk dan memiliki beberapa kelemahan :

  1. Jika skenario akan gagal dan ada pemanggilan langkah bertingkat, Anda hanya akan mendapatkan definisi langkah yang dipanggil terakhir di pelacakan tumpukan. Mungkin sulit untuk menemukan dari tempat mana stepdef terakhir dipanggil
  2. Panggilan ke stepdef terkadang lebih sulit ditemukan dan dibaca daripada metode ruby
  3. Metode Ruby memberi Anda lebih banyak kekuatan daripada memanggil langkah-langkah dari langkah def

Aslak Hellesøy merekomendasikan untuk mengekstrak tindakan populer ke Dunia daripada menggunakan kembali langkah-langkah. Ini mengisolasi tindakan tersebut di satu tempat, membuat kode ini lebih mudah ditemukan. Anda juga dapat mengekstrak kode ke kelas atau modul Ruby biasa.

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

Berikut adalah diskusi yang berguna tentang masalah ini di milis Ketimun - tautan

Andrei Botalov
sumber
2
Saya yakin pendekatan ini jauh lebih baik daripada memanggil fungsi langkah atau langkah untuk alasan yang sama seperti yang disebutkan di atas.
pisaruk
2
Ini memiliki manfaat lain. Menggunakan Idea (atau Rubymine), Anda dapat dengan mudah melompat ke definisi fungsi, tetapi tidak ke langkah-langkah dalam langkah% {...}.
slipset
juga pengaturan ini mengikuti prinsip KERING
Sorcerer86pt
2
Meskipun saya mengalami masalah langkah menggunakan kembali, saya pikir ini hanya buruk. Login hanyalah jumlah dari langkah-langkah yang berbeda: "mengunjungi sesuatu", "mengisi sesuatu". Cara alami adalah menggunakan kembali langkah, alih-alih mengubah setiap langkah menjadi panggilan ke fungsi. IMO, memanggil langkah-langkah di dalam langkah sebaiknya ditingkatkan.
dgmora
9

Sebaiknya gabungkan langkah Anda dengan% {} daripada tanda kutip. Kemudian, Anda tidak perlu menghilangkan tanda kutip ganda yang harus sering Anda gunakan .:

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
Rimian
sumber
5
Ini seharusnya menjadi komentar, bukan jawaban.
Kelvin
1

Gunakan kembali kata kunci dalam file fitur yang akan memberikan kode dapat digunakan kembali.

Sangat TIDAK disarankan untuk memanggil definisi langkah dalam definisi langkah.

Saya akan menulis file fitur saya dengan cara ini,

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       |

Dalam definisi langkah saya, (Ini adalah 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
    }
}

Dengan cara ini, ada banyak kode yang dapat digunakan kembali. Diberikan dan Kemudian Anda yang sama menangani skenario yang valid dan tidak valid. Pada saat yang sama, file fitur Anda masuk akal bagi pembaca.

LINGS
sumber