-
-
Notifications
You must be signed in to change notification settings - Fork 689
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
Proposal: Unambiguous Keywords #768
Comments
I like this proposal because it encourages even less ambiguity. You can no longer mix and match Given/When/Then as you see fit. |
The only thing I propose to this is we do a major update to all our APIs with this and only this, because I can see this either being reported 20 times or causing some grievances. That being said, I do like it :) |
I feel like this should be in the realm of a linters rather then in the realm of the interpreters. |
@mpkorstanje that linter would require access to more than the gherkin document - it would also need the step definitions. I think that’s too heavy for a linter. Plus, people don’t use linters. If we add this we could always add an option to disable it, so people with years of legacy scenarios can go on with their lives. Interested in your perspective @mattwynne @sebrose |
I guess this would necessarily require a change in the messages, which only contains the difficult-to-interpret synonym used in tests. |
I very much like this proposal. It also mirrors the behaviour that has been implemented in Perl's implementation (pherkin/test-bdd-cucumber-perl) since before 2013. |
I like this proposal too. From my point of view, it's not just about language clashes, it's also about wanting to be able to do different technical stuff during context, action and outcome phases of a scenario. For example, if I'm using some kind of driver adapter to connect my steps to my app, I would like to be able to use the domain-driver during It would be super-awesome if there were messages (that front-ends could them build hooks for) that told us when we were moving from context into action, from action into outcome phases of the scenario. But keep that out of scope for now! |
I'm a fan of this. The example in the original summary is exactly the kind of thing I have seen happening in practise.
It could work like a deprecation - ship the change whenever, have it raise a prominent warning at runtime initially but not fail (unless you opt in early), then move to hard failure in a major release after X months? Another minor facet: cucumber-js currently exposes the generic |
I love your thinking here @mattwynne - about separating the context/action/outcome scopes, and giving the user control over how they are created. It's something @joshski and I have been discussing regularly since we paired on the cucumber electron subscond tdd code a couple of years ago. We ended up implementing this pattern ourselves, but it would be much cleaner if it were part of Cucumber itself. |
@davidjgoss - regarding removing |
@aslakhellesoy I've looked through that thread but struggling to see the overlap - |
I also think a warning would be suitable as a first step, with an option to turn warning into error. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed in a week if no further activity occurs. |
This issue has been automatically closed because of inactivity. You can support the Cucumber core team on opencollective. |
Really like this idea. Want to recap to check my understand and see if we can determining next steps
Questions:
Implementation Plan
Thoughts? |
@charlierudolph sounds like a plan to me.
Still no IMO, because fundamentally There is also the |
Presumably, yes. If the fundamental complaint is that |
Dependent on work involved, I would say maybe to start with do the smallest change (That would in theory permit both Given("x") and When("x"), and then maybe later set it up to prevent them. But I'm only spitballing at the moment. Also shared this link with slack as we were discussing it recently. |
I would prefer that this be a configurable option. I do occasionally reuse the same steps between |
I really don't like this suggestion:
However, a number of Gherkin implementations do work in this way (SpecFlow, Perl, Behat?). SpecFlow introduced the @StepDefinition annotation to emulate core Cucumber implementations. I support the passing of the keyword to the pickle. |
I also support passing of the keyword to the pickle. But I do not support making the keyword part of the step definition. Major breaking change with no value. |
Discussed on the weekly Cucumber team call; consensus was that since some implementations have had the step-definition-per-keyword behavior (mentioned during the meeting: SpecFlow and Test::BDD::Cucumber (Perl)), it's necessary to add the keywords to the pickles. Additionally, since Cucumber never exhibited this behavior, it's expected to be a major breaking change for all those who have Cucumber-based test suites. In other words: Let's do this in the pickle so more projects can move to the generic parser infrastructure, but lets not incorporate this any further than that. |
It's my action to implement this in the Gherkin (and Messages) libraries up to the Pickle (for as many languages as I can get). |
Extracted from #1741 for ease of review on request of @aurelien-reeves, implements the `messages` side of #768.
#1966) Expand the messages protocol with keyword types Extracted from #1741 for ease of review on request of @aurelien-reeves, implements the `messages` side of #768. Includes minimal Java changes to support the changes in the schema. Co-authored-by: Aurélien Reeves <[email protected]> Co-authored-by: Aslak Hellesøy <[email protected]>
…word (#1741) * Expand the messages protocol with keyword types Extracted from #1741 for ease of review on request of @aurelien-reeves, implements the `messages` side of #768. * Incorporate review comments * Treat all translations associated with multiple keywords as 'General' keywordType * Incorporate latest reviews * Change the enum in the Pickle as per your last comment * Add translation of But/And to the preceeding keyword in the pickle compiler * Rename the "keywordType" field in the Pickle to `type` * Adjust Perl implementation over changed naming of keyword type General * Use Cucumber::Message's constant declarations instead of hard-coded strings * Align Perl's TokenMatcher implementation with Ruby's * Port initial Perl implementation to Ruby * Fix test failures from the latest refactoring * Add step keyword types to token and AST test data * Fix error found while fixing test data * Make sure the 'keywordType' is correctly populated Since it's legal to start a scenario or even a background with a conjunction, it's fair to say that the keyword type is unknown until a keyword with known type is encountered. * Update testdata with keyword and step types Sync to the implementations which have been adapted. * Follow Ruby's token_matcher structure in Perl And fix a syntax error using constants. * Eliminate warnings during Perl tests Based on running tests on the coverted test data, fix a warning about an undefined value being used. * Rewrite Perl's Pickle compiler to follow Ruby's structure more * Expand 'Conjunction's into their implied keyword type * Convert Perl/Ruby token matcher to pattern available in JS&Java too * Port Ruby/Perl implementation of keyword retention to Java * Sync JavaScript testdata * Progress on JS (works, except Markdown?) * Implement keywordType in Markdown Also align the Classic Gherkin implementation * Use hash lookups to get the keyword's StepKeywordType At the suggestion of @ciaranmcnulty, simplify the loop in `match_StepLine` by using a hash lookup. * Add comment as to why the StepKeywordType is overriden to UNKNOWN * Fix typo (capitalization error) * Update and sync Gherkin-In-Markdown test data * Include background steps when the scenario *has* steps * Rename 'keywordType' to 'matchedKeywordType' Change suggested by @ciaranmcnulty to align the field with the names of the other fields which are only available after the token matched. * Synchronise testdata * Adjust PickleCompiler for 'keywordType' type change Now that 'keywordType' is no longer required, it's type changed to Optional, which introduces an additional level of indirection. * Collect all applicable types per step keyword When more than one mapping exists, return the UNKNOWN step keyword type to indicate that the keyword's meaning isn't exact. * Fix temporarly json-to-messages broken test We need to upgrade json-to-messages to use ci-environment rather than the former create-meta. In the meantime to prevent being stuck, we make the test pass * Restore original jsontToMessages test * Report changes from #1972 on gherkin testdata * Add support for keyword type in go * Add StepKeywordType support to GherkinDialect * Add support of step keyword type to php * revert to c# 9 * Implement PickleStep type in php * [dotnet] try build keyword type * [python] Add support of step keyword type * hopefully fixing .NET finally... * Clarify order of operations when computing lastKeywordType * Clarify type of keywordType list * Add PR to CHANGELOG.md * Remove useless 'if' condition * Add again the check * Add more changelog entries for Go Co-authored-by: Ciaran McNulty <[email protected]> Co-authored-by: aurelien-reeves <[email protected]> Co-authored-by: aurelien-reeves <[email protected]> Co-authored-by: Aslak Hellesøy <[email protected]> Co-authored-by: Aslak Hellesøy <[email protected]> Co-authored-by: Gaspar Nagy <[email protected]> Co-authored-by: Björn Rasmusson <[email protected]>
@aslakhellesoy , @mattwynne , @aurelien-reeves , @mpkorstanje Now that #1741 has been merged, what further work is left in this issue, in your opinions? |
I can't think of anything left to do other than starting to integrate this in to Cucumbers. They should all have an option to turn on the strict validation (matching against expression and keyword). I suggest we call this done for now and deal with any problems as we start integrating. |
I agree Aslak. So that we can keep track of the ongoing work to implement this and get it in front of users, I've used the new Github Projects beta to create a cross-org project: https://github.com/orgs/cucumber/projects/11/views/1 I've created an issue in each of the trackers for the JavaScript, Ruby, Java and Go implementations of Cucumber. If @jenisys @gasparnagy @ciaranmcnulty want to add their own issues to that project too, feel free 😄 |
PHP will take a while (it requires Behat to actually use the cucumber parser, first) |
Perl already behaves like this, however, in order to use this work, we need to start using the cucumber parser. |
SpecFlow already behaves like that, so we are done. |
Proposal Summary / Motivation
I've briefly presented this idea on Slack and in the spirit of gathering more feedback I'm posting it here as well.
The Gherkin reference specifically stipulates that keywords should not be taken into account when looking for a step definition [1].
I've personally witnessed in several projects that this can lead to deterioration in test language unless every change is strictly reviewed.
Below is an example of a hastily written patch that breaks the flow of language, but doesn't yield an error (actually taken from my Git history, but modified slightly to anonymize the domain).
When I press the foobar button - Then I should see 2 events in total And I should see these new fields with values | My Field | foo | | Another Field | bar |
[1] https://cucumber.io/docs/gherkin/reference/#steps
Current Behavior
Currently, the following steps would yield ambiguity error.
• Given(“I press button”)
• When(“I press button”)
I don't propose changing this.
However, it doesn't matter which keyword you use in your feature files and the example below runs just fine.
Proposed Behavior
Given the following step definitions.
... and the following feature file.
I propose for Cucumber to fail with a wrong-keyword error. Furthermore, and just as importantly, for this to properly work, any use of
And
andBut
keyword must be interpreted as if they were of the same type as the previous step.I've tried to outline this behavior with some test cases here.
The text was updated successfully, but these errors were encountered: