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
How can I specify step definition file for each feature file? #748
Comments
Very interesting. cucumber-js has nothing built in like the cucumber-java example you gave. The idea I like for this type of thing, is pushing this logic switching into your world setup or instance. Either way you end up with only one step definition. You can have multiple world definitions that you switch between when defining your support code or have a single world instance that exposes different methods based on context. We don't currently expose the file of the current scenario to running steps but you could use tags to determine your context. |
We actually have same need for this. We are using nightwatch-cucumber to run selenium tests and our only solution for now is to add a prefix to each step:
vs
This helps us avoid ambiguous step definitions, but leads to really unreadable feature files. Could this be realized with some hooks or alternative Worlds? |
@leipert what user interface are you envisioning? I believe this logic should live in the world or support for multiple world objects. Then the step definitions just deal with parsing the gherkin matches and passing them to the proper world function. We could add a CLI option for selecting which world object to use. For the moment if you would like to have multiple worlds / step definitions you can achieve this by putting your code in separate folders and only requiring one of them per run (using the --require CLI option). |
Well, "the cucumber book" specifically discourage this way of designing steps. Step is shared between scenarios by design, the same sentence should has consistent meaning despite the feature using it. Once you introduce the scope of steps, it is really easy to create language trap. So far only tags are close to your purpose in cucuber.js. But only hooks can declare they are specific to tags. If you are certain it is right way for your people, you may invent a DSL, perhaps simple as [feature name] in step pattern. |
Thanks, @pinxue . Very useful response. However, I can't understand it:
A same action phrase could have different meanings in different contexts. But it's ok. It's good to know the options I have, Actually, we're already walking on a internal DSL to achieve it, Thanks a lot. |
Thanks for your answers @pinxue and @robsonrosa.
I see the following approaches to solve the problem for us :
That being said, we probably will go with 3., if the maintainers of cucumber.js think scoped step definitions are out of scope (pun intended) for this project. @robsonrosa I would be interested in your solution, once you have one. |
IMO scoping is definitely needed. As your application grows, the number of features expands and you will end up with conflicting descriptions in different contexts. In my company, our product has hundreds of features and QA has test cases in 100k range. Yes, I think you should consider context instead of scoping. It is the BA and QA who should be writing these tests and any custom DSL is bounded to create confusion and resistance. The Feature/Scenario already provide contexts by definition, that's why the Gherkin syntax has the indentation. Adding tags and custom DSL is a workaround of implementation limitation (i.e. a hack, IMO) instead of a solution. Maybe you can consider this while considering #745 ? How about extending i.e.: import {defineSupportCode} from 'cucumber'
defineSupportCode(({ Scenario, Given, When, Then }) => {
Given(...)
When(...)
Then(...)
Scenario('<match scenario description>', ({ Given, When, Then}) => {
Given('<take precedent of non-contexted>', ...)
...
})
}) |
I learn BDD from http://fitnesse.org/ so I may look at BDD differently than in the cucumber community. |
Paging @richardlawrence |
This is an area where Cucumber is particularly opinionated. It's built around the belief that teams should grow a ubiquitous language, where words and phrases mean exactly one thing in the context of an application and are used consistently. Keeping step defs global maintains a positive pressure to avoid ambiguity. In the rare cases where an application has multiple distinct bounded contexts (in DDD terms), you would simply divide your Cucumber suite along the same lines your application is divided to reflect that boundary, and step defs would be global within each bounded context. |
An article about working with Cucumber and creating boundaries. It implements some of the ideas on this page but doesn't present any great solutions as @richardlawrence has mentioned that you can't configure Cucumber to focus on one a particular class for step definitions. http://confessionsofanagilecoach.blogspot.com/2017/05/teaching-cucumbers-about-boundaries.html |
As @leipert said, global variables are bad. I think those of us in the CucumberJVM world are only getting half the story. Cucumber (non JVM) uses a tidy World concept which is a global memory space for the duration of the Scenario. After the Scenario is executed, it is destroyed. This feels like a good solution. But... I've not seeing a good implementation of this pattern in CucumberJVM. So if Cucumber forces us to have a flat/global namespace for step definitions, and CucumberJVM had a clear design pattern for implementing the World pattern, then I'm a little happier. Up to this point, CucumberJVM + World pattern == overly complicated solutions. So far, everything I've seen is more complicated than simply letting me control which step functions go with which feature file. So far the alternatives I've seen give me nothing more valuable for all the effort/complexity. Other types of Cucumber have better World solutions. Ultimately, even with the World pattern I'm still be unhappy because I know there will be information loss when going from feature file to steps. If I spend great effort: putting my feature files in a good organization, creating good feature file names, declaring my feature in a smart way, naming my scenarios in a smart way--all context is tossed out the window and I'm forced to work with global step definition namespace. |
I can only think of keeping the relationship out of the validations of the system and simply add wildcards on the paths for the tests, and make them work, even if it takes modifying some open source framework. might give it a shot as our project grows. |
I understand your goal, but I would not recommend it. Alternatively you could make two different configuration files. |
@robsonrosa @leipert I share your opinion |
@cristianmercado19 Sorry, no. I am not using cucumber js anymore. |
Ups... I like the way to write feature file completely isolated from the step's implementation. |
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. |
My Goal
I am trying to create a scalable structure of features and step definitions for a large application and my first shot was trying to link step_definition files to features so that I could use the same step pattern for different step definitions.
My Code
I show my current example:
My folder structure:
In my
sample.feature
I have:In my
example.feature
I have:The
Given
andWhen
steps are defined at/common/common_steps.js
file and works fine.The
Then
step is defined both tosample_steps.js
andexample_steps.js
but differently.In my sample_steps.js I have:
And, finally, in my example_steps.js I have:
The Error
My main goal is to have all green here, but of course, it doesn't work and I get this obviouly error:
Cucumber-JVM
I know that in cucumber-jvm we can specify a
glue
attribute that links features and step_definitions and it's exactly what I'm looking for, but in cucumber-js. Example in Java:Finally
How can I achieve the same as cucumbr-jvm using cucumber-js?
The text was updated successfully, but these errors were encountered: