Skip to content
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

[Feature Request] Gherkin: Extend background section to support before and after actions #564

Closed
vvolverine opened this issue Feb 2, 2019 · 15 comments
Labels
⌛ stale Will soon be closed by stalebot unless there is activity

Comments

@vvolverine
Copy link

Summary

There is no possibility to specify which actions(steps) to perform after scenario.

Expected Behavior

To specify in background section keywords like After/Before and then steps that should be performed.

Current Behavior

Background section contains only steps that will be executed before each scenario.

    Feature:

      Background:
        Given every time initial state

      Scenario: dummy scenario
        Given some state

Possible Solution

Extend the background section in the next way

    Feature:
    
      Background:
        Before scenario:
            Given every time nothing
    
        After each scenario:
            Given report generated
    
        After success scenario:
            Given every time nothing
            
        After failure scenario:
            Given screenshots are captured          
    
      Scenario: dummy scenario
        Given some state

I'm looking for feedback from Cucumber core team. Once we will agree on design and on this feature in general I will be able to provide pull request for this functionality.
This implementation will work similar to current background - just concat all steps to one scenario(pickle), possible there will be require to add field to PickleStep that will specify the scope(before, after, after success, etc).
Support from Cucumber frameworks should be added in the future, as happens with new Rule keyword #416 .
The keywords After failure scenario should be also part of gherkin-dialect and should be configurable externally.
New implementation will be backward compatible - if there is no groups in background section, the all steps should be treated as a before steps.
Scenario Outline should be also supported and in the same way as the supported today for Background section.

Context & Motivation

At current point industry looking for feature files as a single point of trust. This is a fundamental part of the project that clear for everyone like business, management, development and test team. By this, all behaviors for application should be specified in one place and in general(native) language. This help to understand and maintain the feature files better.
During the scenario lifecycle any type of background activities required - like open the browser, close the browser, cleanup the environment if scenario is success or create an issue in case of failures. There is a lot of other examples that can be found in daily life and based on current experience I can say that hooks is one of possible solution. But hooks hidden in the code implementation and may be visible only at report phase. This is not good, since non-technical part of the team working with text feature files and do not want to go deep into the implementation details.
At next point hooks just an annotation at the method and there is no restriction where to put this method. When code organized in better way then additional class/package created for this, but by mistake or poor design some hooks can be placed inside of 1000+ row class file and can be forgotten. Then this code will produce weird behavior during time execution and time spent for hook identification can worse a lot.
Since Gherkin language already contains the Background section, logically will be to extend this section to support not only before steps per each scenario but the closure activities also. This help to avoid hook usage(in some cases it will be better to use more native/classic language related features for application lifecycle) and specify all behaviors in one place.
Based on this feature file will clearly describe the behavior of application and all background activities that should be the part of automation.
Gherkin language become more and more popular and used as a feature parser in many other frameworks outside of Cucumber ecosystem. I think it will be good idea to extend them with backward compatibility, so that there will be one solid standard for BDD specification across the industry.

@aslakhellesoy what do you think about this enhancement?

@xtrasimplicity
Copy link
Member

xtrasimplicity commented Feb 2, 2019

I'm not a member of the core team, but I don't think the background section is the place for this sort of thing, given background is somewhat synonymous with before/setup.

@xtrasimplicity xtrasimplicity changed the title Gherkin: Extend background section to support before and after actions [Feature Request] Gherkin: Extend background section to support before and after actions Feb 2, 2019
@xtrasimplicity
Copy link
Member

xtrasimplicity commented Feb 3, 2019

On second thought, Github issues are for reporting bugs, so I recommend taking this to the Cucumber slack channel.

@mpkorstanje
Copy link
Contributor

I think feature requests are best done in tickets. Slack is too ephemeral and doesn't provide fundamental changes the amount of daylight they need to be properly developed.

@mpkorstanje mpkorstanje reopened this Feb 3, 2019
@xtrasimplicity
Copy link
Member

@mpkorstanje No problem - I was a little unsure and then read https://cucumber.io/support#issues and figured I'd close it off. I can see the merit of both sides. :)

@mpkorstanje
Copy link
Contributor

Eh. There is some mixed messaging going on about that.

@vvolverine
Copy link
Author

@mpkorstanje thank you for reopening! based on recent examples for Gherkin Rules implementation(#416 #378 and #414, and original #250 ) looks like it is better to track activities as issues. Seems many open source communities follow this practice. Anyway, thank you for slack link.

So, the problem statement still there - end client can specify the steps that will be executed before each scenario, but there is no way to explicitly tell what is going on after and especially what to do based on scenario outcome(Success or Failure).
This will lead code workarounds(hooks) that understandable only for technical part of the team(again, only in case of well design codebase). I agree that in case when hook action doesn't have any business related functionality - like to close the connections, code implementation via hook is a good choice. But this is more related to specific language implementation, and in some cases hooks can be replaced with native language expressions.
I agree that historically Background section used for setup, general preconditions and so on. But generally this word may have another, wider sense - everything that happens behind the main stage/actor. So, it can be treated like everything that happens behind the scenario, so before and after make sense here.
I think there is a lot of possible solutions like to create section named Lifecycle:

      Lifecycle:
        Before scenario:
            Given every time nothing
    
        After each scenario:
            Given report generated
    
        After success scenario:
            Given every time nothing
            
        After failure scenario:
            Given screenshots are captured 

or make separation for Scenario Background and Rule Background.
By this I'm looking for core team feedback about this enhancement - does it make sense in scope of current Gherkin philosophy or not? If yes, I think we can find the better way for implementation based on conversation and then include this to the Gherkin core.

@mlvandijk
Copy link
Member

@vvolverine My first thought was that you are describing exactly what hooks are for. But if I understand correctly, your objection to using hooks is that they are not visible to the reader of the feature file?
To understand your use case better, could you give some real world examples of when and how you would like to use the After each scenario, After success scenario and After failure scenario?

@enkessler
Copy link

Warning: Opinions follow

Based on this feature file will clearly describe the behavior of application and all background activities that should be the part of automation.

And that would be...not good. Unless you want your documentation and your test framework to not only be the same tool but the very same file as well.

Based on this feature file will clearly describe the behavior of application and all background activities that should be the part of automation. (emphasis mine)

Which is exactly what it shouldn't be doing in the first place. The abstraction layer of natural languages is there to capture the behavior and intent of the system, not to capture the test framework code that is needed to automate the system. If you want to see both the 'test' and all of the fiddly code that runs that test in the same place, then just use a less abstract test framework (e.g. RSpec, JUnit, etc.)

By this I'm looking for core team feedback about this enhancement - does it make sense in scope of current Gherkin philosophy or not?

Admittedly, I am not a member of the core team. I'm just a noisy person who happens to be near a keyboard. I am, however, confident that the approach of having all code relevant to all people in one file is outside the scope of Gherkin.

@danascheider
Copy link
Contributor

I am a member of the core team (though maybe not the most active member ;) and I agree with what others are saying here. Gherkin is not intended to express technical details; indeed, it is intended to obfuscate them in order to:

  1. Communicate your functionality in a way that business users will easily understand and
  2. Keep your technical team focused on what the external requirements are rather than getting bogged down in technical details to the point where you can't see the forest for the trees.

Feeling the need to convey technical information to business stakeholders is a HUGE process smell and I would recommend you think very carefully about what you're actually trying to accomplish with this. Almost without fail, you'll find another way to do this that is idiomatic to Cucumber.

TL;DR: Cucumber/Gherkin is an opinionated framework and its opinion is that you should NOT do what you're describing.

@vvolverine
Copy link
Author

@enkessler @danascheider thank you for your opinions. I absolutely agree with both of you. Let me correct myself a little bit. This suggested solution not a replacement for hooks - it is extension for current Background section. How it will be used finally - up to the team/project. I saw a lot of examples like:

    Feature:

      Background:
        Given browser open for '<url>'

      Scenario: dummy scenario
        Given click button 'button_name'

Which is awful and terrible, since they express technical details, do not describe the business problem and so on. I have the same strong opinion that technical details should be covered inside of the test automation and should never be exposed to BDD level and feature files should contain only business related context. I mean, that Background keyword utilized in wrong way here, not as designed initially.

Please take a look for my business scenario(example for @mlvandijk ).
As a business we want to increase the customer experience during the shopping process. We want to provide ability to modify the cart during shopping process.
For this next scenarios can be implemented:

    Feature: Shopping cart updates
      As a customer I want to modify my cart during shopping

      Scenario: To verify that item can be added to empty cart
        Given a customer named "James"
        And a customer "James" have empty cart
        When customer "James" put single item to the cart
        Then "James" cart has single item
        When customer "James" remove all items from the cart
        Then "James" cart is empty

      Scenario: To verify that item can be replaced in the cart
        Given a customer named "James"
        And a customer "James" have empty cart
        When customer "James" put single item to the cart
        Then "James" cart has single item
        When customer "James" remove single item to the cart
        Then "James" cart is empty
        When customer "James" put another single item to the cart
        Then "James" cart has some other single item
        When customer "James" remove all items from the cart
        Then "James" cart is empty

Regarding to Cucumber Gherkin explanation for Background section this feature can be rewritten in this way:

    Feature: Shopping cart updates
      As a customer I want to modify my cart during shopping

      Background:
        Given a customer named "James"
        And a customer "James" have empty cart

      Scenario: To verify that item can be added to empty cart
        When customer "James" put single item to the cart
        Then "James" cart has single item
        When customer "James" remove all items from the cart
        Then "James" cart is empty

      Scenario: To verify that item can be replaced in the cart
        When customer "James" put single item to the cart
        Then "James" cart has single item
        When customer "James" remove single item to the cart
        Then "James" cart is empty
        When customer "James" put another single item to the cart
        Then "James" cart has some other single item
        When customer "James" remove all items from the cart
        Then "James" cart is empty

Looks better, but if repeatable Given steps moved to the background section as a precondition why not to move repeatable When and Then steps at the same level as a postcondition?

    Feature: Shopping cart updates
      As a customer I want to modify my cart during shopping

      Background:
        Before scenario:
              Given a customer named "James"
              And a customer "James" have empty cart
    
        After each scenario:
              When customer "James" remove all items from the cart
              Then "James" cart is empty

      Scenario: To verify that item can be added to empty cart
        When customer "James" put single item to the cart
        Then "James" cart has single item

      Scenario: To verify that item can be replaced in the cart
        When customer "James" put single item to the cart
        Then "James" cart has single item
        When customer "James" remove single item to the cart
        Then "James" cart is empty
        When customer "James" put another single item to the cart
        Then "James" cart has some other single item

Each scenario should be completed and independent behavior, ideally no more then one behavior per scenario. There should be single responsibility principle. Please correct me if I have wrong understanding. In this case everything around us in real world is transactional - if we want to wash hands(behavior), we need first open and then close the faucet(background). If we want to eat the dinner - we need to prepare meal and the clean the dish. If we want to visit restaurant - we need to make the order and then pay the bill. All of this examples reflect the customer experience - to prepare something, to make the actual behavior, to cleanup/complete the cycle.

So, I'm proposing not to replace the hooks by background keywords and start putting technical details to the feature files like - close connections, drop the table, tear down environment and so on, I'm proposing to provide the ability to the end client to specify full flow(as it already partially done by Background keyword) or more correct - collapse repeatable actions(that required by stakeholders) into one place. The same benefits that proposed originally for Background sections - feature files become more readable and understandable.
How it will be utilized - up to the end team, but I have feeling that it is good to reflect in feature file that client able to complete shopping experience, so the shopping center will have empty carts and not over-flooded by carts with dummy items ;)

P.S. One more example - let assume we have set of negative scenarios for some feature. After some manipulation - like send form with incorrect data, there are should be no updates in DB. This repeatable step Then no changes in DB can be put into the After each scenario or After each success scenario section.

@danascheider
Copy link
Contributor

danascheider commented Feb 6, 2019

I still think what you're describing should go in hooks except for the case where you're explicitly testing THAT the customer can empty their cart. It's assumed that you have your test environment set up such that there is isolation between scenarios, so you shouldn't have to have steps in your scenario to make sure the cart is empty at the end. In the example you're giving, I see no reason why more than one of these scenarios would even have the customer empty their cart at the end.

I would write the scenarios more like this:

Feature: Shopping cart updates

  Background:
    Given a customer named "James"
    And an item "A"

  Scenario: Add item to empty cart
    Given James's cart is empty
    When James puts item "A" in his cart
    Then James's cart should contain item "A"

  Scenario: Remove item from cart
    Given James's cart contains item "A"
    When James removes item "A" from the cart
    Then James's cart should be empty

  Scenario: Replace item in cart
    Given an item "B"
    And James's cart contains item "A"
    When James removes item "A" from the cart
    And James puts item "B" in his cart
    Then James's cart should contain item "B"
    And James's cart should not contain item "A"

Honestly, if you have the first and second scenarios here, you probably wouldn't even need the third since that functionality is effectively already tested in the other two. Given that Cucumber scenarios are relatively computationally expensive to run, I would consider carefully which scenarios and steps are actually needed.

I do see what you're saying about where several scenarios have the same final step(s), but I think extracting that step into an "after each scenario" block like you're proposing would take away from the readability of the scenarios. DRY code is a good thing, but it isn't the only consideration.

@vvolverine
Copy link
Author

@danascheider your words sounds right. Yes, I'm think more about the case when stakeholders require to clean up the cart(general state). Like in example - manual flow will be look like - put item to the cart, and then remove them after the test. Also, please treat my example just as example, not a real case/implementation of feature file.
Also, I'm not sure that real life will count Background section in each feature file - this is more like an optional case for convenience. And the extension of background - not a silver bullet for any case, but optional ability to cases when business require this.
Looking for example in reference for Gherkin, there is very thin border between hooks and background. Because based on logic from above comments Background section also can be removed from feature file and replaced with hooks, since business do not require to know about how is a global administrator and so on(this information can be a part of final report and can be retrieved from hooks).
Looks like, each case unique and there is no golden rule to say this should be done by hooks or in feature file.

I also agree about DRY principle, for me it should not be applicable to the Gherkin, since Gherkin is a form of native language not a programming language. Activities that today looks similar and can be grouped, tomorrow can be split out based on the changes in requirements and effort that will be spent to split them will be greater than support them independently at the beginning.

Case from reality - that stakeholders are a little bit technical. They do not dive deeper in programming language details as a senior developers but they understand system very well, and they understand why cleanup required in some times and they also requested some verbose actions after scenarios as I described above.

So, if there is no solid justification for current Background usage(reference documentation ask to use it very carefully too) but it there and working well for years, may be try to extend this section as proposed above and prepare documentation, that this should not be used to expose technical implementation to the feature level, but to use in case when stakeholders require before and after precondition verbosely as part of feature?

P.S. It is not a part of original discussion, but I can say that all 3 scenarios from example above are valid - add to empty cart, remove from cart, add A, remove A and add B. Because you may remove item - cart is empty, you try to add new item to the cart - cart contains previously removed item and new one(A and B, depends on many factors)

@stale
Copy link

stale bot commented Apr 7, 2019

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.

@stale stale bot added the ⌛ stale Will soon be closed by stalebot unless there is activity label Apr 7, 2019
@stale
Copy link

stale bot commented Apr 14, 2019

This issue has been automatically closed because of inactivity. You can support the Cucumber core team on opencollective.

@stale stale bot closed this as completed Apr 14, 2019
@ranithamr
Copy link

how to pass params in background? is that possible or any alternatives available

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
⌛ stale Will soon be closed by stalebot unless there is activity
Projects
None yet
Development

No branches or pull requests

7 participants