-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for Calling Steps Explicitly #634
Comments
+1, it's in Cucumber so to me there's no reason to want things differently for its JS port Edit: Didn't know that was considered anti pattern by so many people. No strong feeling (nor need) for this then, I'll give the devs who experienced it the benefit of the doubt. |
See this comment as this has been suggested a few times and cucumber/cucumber-ruby#401. @aslakhellesoy @mattwynne do you still see this as an anti pattern? |
@charlierudolph While the concept of invoking an existing step has been mentioned in the comment/issue you mentioned, they seemed to cover a lot of ground, including calling steps from other steps in Gherkin. My request is JS-only, and as such I believe it addresses some of the previous concerns. |
Yes we still consider this an anti pattern. It encourages treating steps as scripting instructions and a more imperative language in some steps which results in higher coupling between steps, reduced maintainability and other negative effects. All use cases for calling steps from steps I've seen so far are better addressed with other approaches. @machineghost an improved regular expression would probably be the solution to A. I don't understand your point in B, can you please elaborate? |
@jbpros Thanks for the reply. However, I don't think an improved regular expression solves A. In my example:
there are two entirely distinct steps. Now, obviously that's just an example; in a real test you wouldn't have two identical steps. Which leads me to B ... So, in my experience at least, it's extremely common to repeat earlier steps in later steps. Test 1 is login, test 2 is login and go view some page, test 3 is login, view some page, then edit something etc. Now you can split that common logic for "login" and "go view some page" out in two ways.
If you choose the latter then your steps read like this:
If you use helper methods, then you instead have:
So by re-using steps you have a series of steps, each relying on the logic of a step a few lines up. If you want to see how it works, if you want to change anything, etc. everything relevant is right there. If you separate everything out in to functions you lose that, which in my opinion makes re-using steps within a step definition (but NOT within a Gherkin test definition) has value. P.S. I'd also like to second @floribon's point; Cucumber proper has this: https://github.com/cucumber/cucumber/wiki/Calling-Steps-from-Step-Definitions You don't want Javascript to lose to Ruby do you? Those people can't even spell |
From the Ruby perspective, while I understand why people want this feature, I often regret that we have it. I think factoring out the automation helper code using something like the screenplay pattern is a much better idea in the long run. |
@machineghost going to close as this doesn't have enough support from the cucumber core team. Some workarounds if you'd like them.
Something I've seen is to have you step definitions merely parse the step argument and then call a function you have defined on your world instance. This way all the real logic and state can live in the world instance and thus you shouldn't be passing anything around. The world instance can call out to helpers to keep its size down, but it should the one holding all the state.
This sounds like test 3 covers everything and if you have a failure in test 1, then test 2 and 3 will fail. If you have a failure in test 2, then test 2 and 3 will fail. Thus I think you could get away with just test 3. This sounds like a full integration test and I think its better to have just a few happy path integration tests and more unit tests / test at lower levels to catch all the edge cases I haven't needed steps to call other steps, as a lot of times I just repeat the step in the gherkin. You gave an example of "view page" which calls the "login" step. And "edit page" which calls "view page". Instead I would have the step definitions do just their specific logic and repeat the step in the gherkin if its part of the process. |
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
As this Stack Overflow answer explains, in (Ruby) Cucumber it is possible to call one step from another:
It seems like this could very easily be implemented in the JS version:
Now I (think I) know what you're going to say: just factor out the logic in to a shared function:
But that approach has a couple downsides:
A) It's more verbose; consider this very simple example of a single repetition:
vs.
... and that's just when you do it once (the more you repeat the more bloat you get), without passing anything around (obviously a real world example would be even more bloated as at the very least you have to pass
this
all over the place).B) It winds up decoupling all of your logic from your steps. Let's say you want to repeat the steps of your first scenario as a step in subsequent scenarios. Instead of the normal step definition, where you have "name of step" on line 1 and "definition of step" on line 2, you have:
So, I know this sounds like something only a non-programmer would want, but as a programmer of 10+ years I think this would actually be more beneficial to programmers than to people who want to create real logic in Gherkin syntax.
The text was updated successfully, but these errors were encountered: