Cucumber-js: Memanggil langkah dari definisi langkah

Dibuat pada 1 Jun 2011  ·  31Komentar  ·  Sumber: cucumber/cucumber-js

Komentar yang paling membantu

:-1: :-1: :-1: :-1: :-1:

Memanggil langkah dari stepdefs adalah salah satu fitur yang saya harap tidak pernah saya tambahkan ke Mentimun(-Ruby), karena menyediakan begitu banyak tali bagi orang untuk menggantung diri. Itu terjadi karena Ruby stepdefs menggunakan penutupan anonim yang tidak dapat Anda panggil dari tempat lain (kecuali jika Anda melewati rintangan).

Dengan JavaScript, situasinya berbeda; Definisi Langkah menggunakan fungsi kelas satu!

function x_is_something(x, cb) {
  console.log('x', x);
  cb();
}

Given(/x is (.*)/, x_is_something);

Given(/super x/, function(cb) {
  x_is_something(97, cb);
});

Semua 31 komentar

Ketika ini diterapkan, ingatlah bahwa kami berencana untuk menghentikan semua hal selain #steps untuk melakukan ini di mentimun-rb. Lihat https://github.com/cucumber/cucumber/issues/68

Terima kasih Mat. -js hanya akan mendukung langkah() kemudian.

Saya suka itu!

Ada kemajuan dalam hal ini? Sepertinya fitur yang cukup vital.

Ini tidak direncanakan sebagai bagian dari pencapaian saat ini (0,3). Ini _harus_ menjadi bagian dari 0.4.

@mattwynne Saya kira kami ingin mendukung step() juga. Apakah saya benar?

@jbpros kurasa. Mungkin Anda bisa mulai dengan #step . Ini lebih mudah diterapkan karena Anda hanya menjalankan satu langkah daripada mengurai Gherkin.

Saya pribadi akan senang menggunakan Mentimun tanpa fitur ini, saya tidak pernah menggunakannya dan menganggapnya sebagai praktik yang buruk. Saya selalu lebih suka mendelegasikan ke metode sebagai gantinya.

Pada akhirnya, jika kita akan mendukung ini, saya lebih suka melihatnya diimplementasikan di Gherkin, jadi Anda memiliki cara untuk mendefinisikan langkah makro yang memetakan ke banyak langkah tingkat rendah lainnya. Mentimun kemudian hanya disuruh memanggil yang tingkat lebih rendah dan hampir tidak perlu tahu ada pemetaan yang terjadi. Itu akan menjadi preferensi saya.

TL;DR: Haruskah kita benar-benar menambahkan steps() / step() ke Cucumber.js (dan -jvm, -ruby 2, dll.)?

Saya sangat setuju dengan Anda Mat. _Sayangnya_, ini adalah fitur yang paling dicari saat ini di Cucumber.js.

Seperti yang saya pahami, banyak orang menganggap definisi langkah sebagai _metode_ atau _fungsi_. Cara saya melihatnya, mereka memetakan antara beberapa kalimat bahasa yang fasih dan potongan kode bahasa pemrograman, tidak lebih. Ini memiliki implikasi mendalam tentang bagaimana kita memperlakukan binatang-binatang itu.

Dari perspektif programmer, definisi langkah terlihat seperti metode. Saya melihatnya sebagai kelemahan di Cucumber_s_ hari ini. Definisi langkah tidak boleh diekspos sebagai API melainkan sebagai peta terjemahan eksplisit, kamus, sehingga untuk berbicara.

@msassak sudah memiliki pemikiran yang menarik tentang ini dan saya pikir dia melakukan pekerjaan yang baik dengan memodelkan ulang "pemetaan" itu di Mentimun 2.0.

Saya harus mengatakan bahwa saya enggan untuk mengerjakan masalah ini di Cucumber.js sekarang. Di sisi lain saya tidak ingin melakukan retensi fitur hanya karena selera/pendapat pribadi saya.

:-1: :-1: :-1: :-1: :-1:

Memanggil langkah dari stepdefs adalah salah satu fitur yang saya harap tidak pernah saya tambahkan ke Mentimun(-Ruby), karena menyediakan begitu banyak tali bagi orang untuk menggantung diri. Itu terjadi karena Ruby stepdefs menggunakan penutupan anonim yang tidak dapat Anda panggil dari tempat lain (kecuali jika Anda melewati rintangan).

Dengan JavaScript, situasinya berbeda; Definisi Langkah menggunakan fungsi kelas satu!

function x_is_something(x, cb) {
  console.log('x', x);
  cb();
}

Given(/x is (.*)/, x_is_something);

Given(/super x/, function(cb) {
  x_is_something(97, cb);
});

CLOSED (WONTFIX) :hammer:

Saya tidak yakin saya mengerti bagaimana step() akan lebih baik daripada panggilan fungsi JS sederhana di sini. Bukankah itu yang akhirnya dilakukan, dengan lapisan tipuan tambahan (yaitu definisi langkah untuk membuat permintaan GET ke pengguna tertentu yang masih perlu diterjemahkan ke dalam fungsi JS)?

Saya perhatikan Anda menulis _karena saya tidak punya cara untuk memicu skenario_, apakah maksud Anda langkah atau skenario yang disengaja (dalam kasus terakhir, saya dapat melihat apa yang Anda coba lakukan, saya pikir).

Anda masih dapat menentukan pengguna di latar belakang dan mengulanginya dalam langkah When Anda.

Feature:
  Background:
    Given a valid user called Simon
    And a valid user called Sarah
    And a valid user called Johnny

  Scenario Outline:
    When each valid user sends a GET request to /search<query>
    Then everyone's request response code is 400
    And everyone's request response body starts with <body>

  Examples:
    | query  | body |
    | ?foo=1 | ...  |

Dan ya ini berarti menyimpan respons permintaan dalam array dan mengulanginya. Apakah seburuk itu?

Nah, jika Anda memiliki beberapa alur (misalnya alur pembayaran) dan Anda ingin membuka halaman konfirmasi akhir, Anda dapat melalui langkah-langkah yang ditentukan (di suatu tempat) dalam definisi langkah.
Saya setuju bahwa Anda juga dapat mendefinisikan suatu fungsi di suatu tempat dan menjalankannya dari definisi langkah. Tetapi meminimalkan upaya untuk memindahkannya dari langkah ke fungsi. Jika Anda menggambarkan beberapa aliran di suatu tempat di BDD, Anda tidak perlu menghabiskan waktu tambahan untuk memindahkannya ke perpustakaan terpisah, Anda cukup memanggil definisi langkah.

Meminta satu langkah hampir tidak berguna. Saya berpikir untuk mem-porting semua fungsionalitas langkah Ruby di sini. Tetapi karena permintaan saya ditutup, saya tidak akan meluangkan waktu untuk itu.

Terima kasih.

Sedih sekali ini tidak akan diperbaiki, seperti yang dikatakan @cono : menjalankan satu langkah hampir tidak berguna, kasus nyata adalah operasi yang lebih kompleks.

Ini akan sangat membantu untuk membuat beberapa skenario halus dan kemudian skenario lain mengulangi operasi ini. Khususnya ketika langkah-langkah didefinisikan di lebih dari satu file, dalam hal ini alternatif penggunaan kembali fungsi tidak mudah dan juga tidak bersih.

Hai! Saya telah membuat lib yang melakukan persis apa yang Anda minta (panggil satu langkah dari langkah lain), lihat di sini: https://github.com/hackhat/cucumberry
Umpan balik diterima!

@hackhat Terlihat sangat keren. Saya biasanya menyukai bagian sinkronisasi dari definisi langkah. Apakah mentimun-pro hanya sebuah plugin untuk mentimun.js?

@ jlin412 Saya tidak benar-benar tahu cara menelepon, tetapi seperti pembantu untuk mentimun. Terima kasih atas umpan baliknya

@hackhat Untuk membuat langkah sinkronisasi, saya perlu menggunakan sintaks: this.addStep(...)? Apakah saya perlu menggunakan selenium-sync juga alih-alih protractor.js/webdriver.js?

@ jlin412 Anda hanya dapat menggunakan plugin sinkronisasi, lihat dokumen cara melakukannya. Saya menggunakan ponsel jadi saya tidak bisa memberi Anda langkah-langkah yang tepat. Jika Anda bisa menunggu, saya akan menjelaskan lebih baik sekitar pukul 23.30 waktu Portugal.

@hackhat tolong ubah nama proyek Anda menjadi sesuatu yang lain. Lihat hackhat/cucumber-pro#1

@aslakhellesoy Mengubah nama menjadi https://github.com/hackhat/cucumberry

@aslakhellesoy Lalu bagaimana cara merangkai panggilan langkah? Suka mengikuti?

function x_is_something(x, cb) {
  console.log('x', x);
  this.x = x;
  cb();
}
function y_is_something(y, cb) {
  console.log('y', y);
  this.y = y;
  cb();
}

Given(/super z/, function(cb) {
  x_is_something(97, cb);
  y_is_something(8, cb);
});

Itu tidak bekerja dengan baik karena x_is_something akan memanggil panggilan balik sebelum y_is_something memiliki kesempatan untuk menyelesaikan pekerjaannya.

Dan juga, jika langkah menyimpan variabel dalam konteks dunia, itu akan berakhir setiap kali memanggil fungsi, kita perlu mengikatnya seperti:

Given(/super z/, function(cb) {
  x_is_something.bind(this)(97, cb);
  y_is_something.bind(this)(8, cb);
});

Adakah yang punya solusi untuk masalah ini?

Anda perlu menggunakan async dan menggunakan fungsi paralel. Dengan cara ini Anda memanggil
cb utama hanya setelah kedua sub panggilan selesai.
Tentang mengikat Anda dapat menggunakan ini dengan mengikat atau menggunakan variabel penutupan.

Pada Kamis, 14 Mei 2015, 00:15 Yun [email protected] menulis:

@aslakhellesoy https://github.com/aslakhellesoy Lalu bagaimana cara merantainya
panggilan langkah? Suka mengikuti?

fungsi x_is_sesuatu(x, cb) {
console.log('x', x);
ini.x = x;
cb();
}fungsi y_is_sesuatu(y, cb) {
console.log('y', y);
ini.y = y;
cb();
}

Mengingat(/super z/, fungsi(cb) {
x_is_sesuatu(97, cb);
y_is_something(8, cb);
});

Itu tidak bekerja dengan baik karena x_is_something akan memanggil
panggilan balik sebelum y_is_something memiliki kesempatan untuk menyelesaikan pekerjaannya.

Dan juga, jika langkah menyimpan variabel dalam konteks dunia, itu akan berakhir
setiap kali memanggil fungsi, kita perlu mengikatnya seperti:

Mengingat(/super z/, fungsi(cb) {
x_is_something.bind(ini)(97, cb);
y_is_something.bind(ini)(8, cb);
});

Adakah yang punya solusi untuk masalah ini?


Balas email ini secara langsung atau lihat di GitHub
https://github.com/cucumber/cucumber-js/issues/11#issuecomment -101845619
.

+1, ini harus menjadi bagian dari lib.

Apa yang disarankan @mattwynne (tambahkan fitur gherkin yang mendukung penggunaan kembali kode):

    When a
    Then x
    When b
    Then y

---------------------------------

    Define x
        Then p
        And y
        And q

---------------------------------

    Step a
        ...
    Step b
        ...
    Step p
        ...
    Step q
        ...
    Step y
        ...

---------------------------------

Apa yang disarankan @aslakhellesoy (mengekstrak kode yang digandakan ke fungsi js):

    When a
    Then x
    When b
    Then y

---------------------------------

    Step a
        ...
    Step b
        ...
    Step x
        ...
        Call f(p)
        ...
    Step y
        Call f(p)

---------------------------------

    Function f(p)
        ...

---------------------------------

Memanggil langkah dari definisi langkah

    When a
    Then x
    When b
    Then y

---------------------------------

    Step a
        ...
    Step b
        ...
    Step x
        ...
        Call y(p)
        ...
    Step y
        ...

---------------------------------

Saya masih tidak mengerti mengapa kita membutuhkan level abstraksi lain yang tidak perlu, apakah Anda punya penjelasan?

@yunjia ini adalah teori panggilan balik dasar:

Given(/super z/, function(cb) {
  x_is_something(97, function () {
    y_is_something(8, cb);
  });
});

Adapun masalah pengikatan, Anda harus mendefinisikan fungsi-fungsi itu sebagai metode di World Anda:

function World(callback) {
    this.x_is_something = function (x, callback) {
      this.x = ...
    };

    this.y_is_something = function (y, callback) {
      this.y = ...
    };

    callback(); // tell Cucumber we're finished and to use 'this' as the world instance
  };
}
module.exports.World = World;

Kemudian dalam definisi langkah Anda:

Given(/super z/, function(cb) {
  var self = this;
  self.x_is_something(97, function () {
    self.y_is_something(8, cb);
  });
});

Juga, harap perhatikan bahwa definisi langkah sinkron didukung oleh Cucumber.js 0.5+:

Given(/super z/, function() {
  this.x_is_something(97);
  this.y_is_something(8);
});

@inf3rno definisi langkah adalah lapisan terjemahan tipis antara bahasa Inggris biasa dan kode JS. Dengan mengizinkan pemanggilan langkah dari langkah, kami membuat lapisan itu lebih gemuk. Langkah-langkah menjadi digabungkan antara satu sama lain, membuat mereka sangat sulit untuk dipertahankan.

Ini juga mendorong orang untuk menggunakan Gherkin sebagai bahasa skrip, yang sebenarnya tidak sama sekali.

@inf3rno jika Anda ingin menggunakan kembali kode di stepdefs, pindahkan isi stepdef ke fungsi javascript biasa dan gunakan kembali itu.

@jbpros

Ini juga mendorong orang untuk menggunakan Gherkin sebagai bahasa skrip, yang sebenarnya tidak sama sekali.

Bisakah Anda menguraikannya? Saya tidak mengerti apa hubungannya, karena definisi langkah tidak ada dalam gherkin, hanya pola teks yang mirip.

@inf3rno jika Anda dapat memanggil langkah-langkah dari langkah-langkah, Anda melompat kembali ke "Gherkinland": nama langkah perlu diuraikan, dicocokkan dengan definisi langkah yang dapat dieksekusi. Anda pada dasarnya menulis skrip gherkin di dalam gherkin (mereka tersembunyi di dalam definisi langkah JS, tapi itu detail yang membuatnya lebih buruk dari POV pemeliharaan).

@aslakhellesoy @jbpros Idenya adalah bahwa langkah-langkah harus berupa tipe aljabar yang dapat dikomposisi, padahal bukan.

@jbpros , saya akan menggunakan solusi Anda karena saya terbiasa pemrograman di Jawa dan tidak khawatir tentang janji :)

Apakah ada yang pernah datang dengan ekstensi ke mentimun untuk mendefinisikan langkah-langkah dalam hal langkah-langkah lain? Sesuatu seperti

Understand I log in to {site} as {user}, {pass}
    I visit {site}
    I log in as {user}, {pass}

Sedang mempertimbangkan apakah ini adalah ekstensi yang berguna untuk lebih menggambarkan perjalanan panjang pengguna melalui sistem dan lebih suka bekerja dengan karya sebelumnya.

Utas ini telah dikunci secara otomatis karena tidak ada aktivitas terbaru setelah ditutup. Silakan buka edisi baru untuk bug terkait.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat