Deprecate `And` and `But` functions for step definitions
aslakhellesoy opened this issue ยท 19 comments
Current behavior
Step definitions can be defined with Given
, When
, Then
, And
and But
- see
cypress-cucumber-preprocessor/lib/index.ts
Lines 65 to 71 in b629567
Desired behavior
Step definitions can be defined with Given
, When
and Then
. This is what Cucumber.js does: https://github.com/cucumber/cucumber-js/blob/01368ca6e3c9b097a7a88bb72de5beeddb4a0326/src/index.ts#L45-L51
Here is an example illustrating why:
Feature: banking
Scenario: Overdraft
Given I have an overdraft limit of 50
And I have a balance of 300
When I withdraw 330
Then my balance should be -30
With the currentl API, people might implement step definitions this way:
Given('I have an overdraft limit of {int}')
And('I have a balance of {int}')
But what if I add a new scenario:
Scenario: No overdraft
Given I have a balance of 300
When I withdraw 330
Then my balance should be 300
And I should be told my overdraft limit is 0
It no longer makes sense that the step defnition is defined with And
.
The And
and But
keywords only belong in Gherkin. Step definitions are reusable in any order, and should therefore not use And
and But
.
Checklist
- I've read the FAQ.
- I've read Instructions for logging issues.
- I'm not using
cypress-cucumber-preprocessor@4.3.1
(package name has changed and it is no longer the most recent version, see #689).
Fixed with v13.0.0.
Wow. This is a huge breaking change, isn't it?
Could you please explain, why And
/But
steps are not reusable? And
/But
after Then
come with a should
that And
/But
after Given
or When
do not. As in your examples. Thus they cannot be mixed up. The syntax is clear. Without should
it is an action (clicks etc), with should
it is a check (cy.contains()
etc).
I also have those reusable steps in different files like And-after-Then.ts
and And-after-When.ts
.
Wow. This is a huge breaking change, isn't it?
You thinking this make me suspect that you're misunderstanding the implications of this change. This only affects the method you use for defining steps, aka Given(..)
, When(..)
and Then(..)
. With this change, you would still use the keywords And
and But
in the gherkin / feature files.
However, with a file a
Feature:
Scenario:
Given something
And another thing
.. then another thing
is implicitly considered to be a given-step and it should be declared using Given(..)
.
Thus, the only thing I expect anyone to change is swapping out calls to And(..)
and But(..)
with the more appropriate methods.
Ah, now I understand. But in German this does not work. The sentence structure after Dann
(German for Then
) is different than after Und
(German for And
).
But I already found a workaround. I just use defineStep
instead.
import { Before, defineStep, Given, Step, Then, When } from '@badeball/cypress-cucumber-preprocessor';
export const Und = function (description: string | RegExp, implementation: IStepDefinitionBody<unknown[]>) {
return defineStep(toCucumberExpOrRegExp(description), implementation);
};
export const Aber = function (description: string | RegExp, implementation: IStepDefinitionBody<unknown[]>) {
return defineStep(toCucumberExpOrRegExp(description), implementation);
};
FYI, defineStep()
is going away from cucumber-js (cucumber/cucumber-js#2043) and this will eventually be reflected in this lib as well.
FYI,
defineStep()
is going away from cucumber-js (cucumber/cucumber-js#2043) and this will eventually be reflected in this lib as well.
I guess this means that my workaround will get quite ugly then, e.โฏg. mapping everything to When
or so. But thanks anyway!
Ah, now I understand. But in German this does not work. The sentence structure after
Dann
(German forThen
) is different than afterUnd
(German forAnd
).
@iomedico-beyer can you give me a concrete example of a sentence/step that would be different with Dann
and Und
? I'm one of the maintainers of Cucumber and understanding this would be helpful.
@iomedico-beyer can you give me a concrete example of a sentence/step that would be different with
Dann
andUnd
? I'm one of the maintainers of Cucumber and understanding this would be helpful.
Sure :)
Then there should be an "OK" button
And there should be a "Cancel" button
is in German
Dann sollte es einen "OK"-Button geben
Und es sollte einen "Cancel"-Button geben
Subject and predicate swap places.
A linguistic alternative would be to add a "dann " to the Und
:
Dann sollte es einen "OK"-Button geben
Und dann sollte es einen "Cancel"-Button geben
However, that sounds more than a little odd.
(And I would have to do a little transformation to the strings, removing the "dann " prefix.)
woulnd't it be better to support defining steps as both 'When' and 'And' like other bdd frameworks?
woulnd't it be better to support defining steps as both 'When' and 'And' like other bdd frameworks?
I guess the idea is that When
is more descriptive/clear than And
, because And
can also be used after Given
and Then
.
Also the framework can narrow its matching to look e.โฏg. only in When
declarations for a specific And
test step (that comes after a When
test step) โ although I'm not sure if this is particularly helpful (Given
and When
seem semantically similar enough for me for And
to match both).
Given and When seem semantically similar enough for me for And to match both
Recommended reading: A little tense
Recommended reading: A little tense
Interesting! Here is a typical test of mine translated into English and trying to follow that guide:
Given I went to the "Select analysis" page
And I clicked on "Create new analysis"
When I click on "Go back"
And I click on "Discard config"
Then I should be on the "Select analysis" page again
So for the clicking steps I would have to implement the "clicked" variant with the Given
command and the "click" variant with the When
command. I'm not quite sure if that's a good idea. What do you think?
Sorry if that's awfully off topic!
I agree this was hastily implemented. This feels a bit too opinionated from the author.
what a shame, AND/OR is widely used in Gherkin sintax and should reflect in the tests.
And(..)
and Or(..)
has afaik never been exported members in cucumber-js
(ref. cucumber/cucumber-js#1118 and cucumber/cucumber-js#1615) and this has not changed recently. The only thing that has changed recently, is the feature alignment between this preprocessor and cucumber-js
, where this preprocessor aims for feature identicality. Exporting And
and But
was simply a mistake and did not correctly reflect the experience found in cucumber-js
.
Furthermore, cucumber-js
is not developed here. Changes there can trickle down and be reflected here, but not the other way around, because this preprocessor simply isn't associated with Cucumber in any way. If you think it's a mistake that cucumber-js
doesn't export And(..)
and But(..)
, then I suggest you take it up somewhere more appropriate.
I want to highlight the following comment from Mar 16, 2021: cucumber/cucumber-js#1615 (comment)
We're never going to add
And
andBut
as step definition methods.
@badeball ,
Thanks for the update, so we can have in our feature file still the And
or But
.
However in our code we should state Given
, When
or Then
E.g.
Feature file:
Given I open website
Then my website is shown
And the data is shown
Code:
Given('I open website', () => {
do stuff;
});
Then('my website is shown', () => {
do stuff;
});
Then('the data is shown', () => {
do stuff;
});
Making it also easier to understand if the command is a given
, when
or then
command.
Ah, now I understand. But in German this does not work. The sentence structure after
Dann
(German forThen
) is different than afterUnd
(German forAnd
).But I already found a workaround. I just use
defineStep
instead.import { Before, defineStep, Given, Step, Then, When } from '@badeball/cypress-cucumber-preprocessor'; export const Und = function (description: string | RegExp, implementation: IStepDefinitionBody<unknown[]>) { return defineStep(toCucumberExpOrRegExp(description), implementation); }; export const Aber = function (description: string | RegExp, implementation: IStepDefinitionBody<unknown[]>) { return defineStep(toCucumberExpOrRegExp(description), implementation); };
are you still using this method? where did u place this, in your step definition fille?
are you still using this method?
No, in the end we switched to English.
where did u place this, in your step definition fille?
No, somewhere in cypress/support/
.