Cucumber-js: Before/After feature hooks and hacks

Created on 23 Aug 2017  ·  10Comments  ·  Source: cucumber/cucumber-js

I understand the reasoning behind not having BeforeFeature/AfterFeature feature hooks. Tests should ideally be isolated. However, for practical performance reasons it can be preferable to setup things like database fixtures once per feature.

The workaround specified in #614 is inadequate because:

  1. It will not call After when consecutive features have the same tag.
  2. It will not call After if the tagged feature was the last test in the build.

Previous to 3.0.0 it was possible to hack in this functionality using the context passed as the first argument of registerHandler('BeforeFeatures').

Any thoughts on accepting a PR for this functionality, or providing a similar context in 3.0 to at least make the hack possible again?

Most helpful comment

+1 for BeforeFeature/AfterFeature hooks
I agree with the need to balance performance with test isolation. The way the framework is built right now, there is very little that connects the scenarios in a single feature, except for the background steps which are repeated. In some cases, we may not want the background steps to be repeated, but rather, have them happen once at the beginning of the feature, and get torn down only once all scenarios have completed.

All 10 comments

It will not call After when consecutive features have the same tag.

I don't understand. Can you please give more detail around this? You could create an After hook that is specific to the tag being present or not. Note the tag syntax has changed since that workaround was given.

It will not call After if the tagged feature was the last test in the build.

Again, I don't understand this, please explain more. You should be able to use an After hook, but you do lose the context of whether or not this is the last one. Ideally you don't need to do any teardown here.


Also you are trying to make scenarios be connected which is discouraged. I would suggest one of the following:

  • disconnect the scenarios
  • execute cucumber-js multiple times loading different support files and use BeforeAll / AfterAll

To be clear, the workaround I'm referring to is:

this.Before({ tags: ['@featurehook'] }, function () {
  // log user in (if needed)
})

this.Before({ tags: ['~@featurehook'] }, function () {
  // log user out (if needed)
})

Consider some features:

@featurehook
Feature: feature 1
   Scenario: scenario 1

@featurehook
Feature: feature 2
   Scenario: scenario 2

Feature: feature 3
   Scenario: scenario 3

@featurehook
Feature: feature 4
   Scenario: scenario 4

If they are run in the order above, the teardown won't happen between feature 1 and feature 2. The teardown won't happen after feature 4 either because there will be no other test matching ~@featurehook (admittedly this can be fixed with AfterAll).

I am not trying to make scenarios connected, for me it is being free to decide on a tradeoff between isolation and performance.

Take the example of a test that sets up a test SMTP server with different configurations:

@smtpConfig1
Feature: ....

@smtpConfig2
Feature: ....

There may be side effects between scenarios by not tearing it down, but the trade-off between purity and performance might be worth it in this case.

Sorry but this isn't something I think should be supported. There is the ability to share state across all scenarios and across a single scenario which covers the vast majority of cases. Your example in the last comment (with @featurehook) isn't solved by having BeforeFeature / AfterFeature anyway.

+1 for BeforeFeature/AfterFeature hooks
I agree with the need to balance performance with test isolation. The way the framework is built right now, there is very little that connects the scenarios in a single feature, except for the background steps which are repeated. In some cases, we may not want the background steps to be repeated, but rather, have them happen once at the beginning of the feature, and get torn down only once all scenarios have completed.

Since I use a service like Browserstack, which is perpetually slow and painful to work with (and so are other remote server providers like Saucelabs), I normally use BeforeFeature and AfterFeature event handlers to setup selenium sessions and teardown per feature file.

Therefore, the scenarios related to that feature mentioned in my file run together and to start afresh post each scenario, I refresh the browser screen and the state of my app is refreshed for my tests. So in a way they are isolated and it also does not affect the test performance.

This should be considered as a case to bring the Before/After feature hooks back to be used than executing cucumberjs per feature file as suggested above.

BeforeFeature/AfterFeature hooks are essential for e2e/uat/bdd/call-it-whatever-you-want testing that cucumber is made for.

The major "competitors" of Cucumber support this (e.g. JBehave, RobotFramework), and without any hacks; it's a proper feature of the framework.

This issue is definitely a blocker for using Cucumber.

Hi... I am facing an issue related to this. In my case, I use tagged Before and After hooks to create/delete data that will be used to test the UI. In the Before hook I hit an API endpoint and create the data, and in the After hook I hit another API endpoint to delete it (I save the objects' id's returned in the create response, and then I build the delete payload with those id's)

The problem is that, when the scenario that uses that data (and triggers the hooks) is the last to be executed, the after hook never gets triggered...

Any way to workaround this??

Thanks

+1 for Before and After Feature.
Our use case is this: We find bugs in certain browsers that don't appear in others.

We want to tag a feature like so:

@ie-8-only
Business Need: IE8 should have limited functionality, but what is displayed, should be displayed correctly

@no-access @ssl-insecurity @security @BUG-1876
Scenario: No access
   Given I am on the home page
   When I see that my browser is not supported
   Then I should not be able to access the core site functionality

@formatting-issue @bugs @BUG-1210
Scenario: The menu should not be formatted like a staircase
   For the users to be able to navigate to the about us / contact us area of the site, the site navigation should be active
   Given I am on the home page
   When I see the menu
   Then it should be displayed in a line

This will allow us to close the browser and open IE in a BeforeFeature hook, and reopen the browser we are using for the rest of the suite in the AfterFeature hook. Closing and reopening the browser takes a lot of time when you are doing it for every Scenario, which would make this a great feature to use.

Note:
I know there are alternatives that involve the world object (setting current browser there, and only closing if the browser is not what we need in the beforeAll Hook for these), but it seems simpler to do it this way, and it has to be done in a hook already or Selenium decides it's going to throw a hissy fit half the time.

There are other times where you might want to attach text to the Feature as an added description for it in a BeforeFeature Hook, which is another example of where this would be useful

I think as well before/after feature hooks would be useful on certain types of tests. For example Specflow, the Cucumber library for .NET, has these implemented:
https://specflow.org/documentation/Hooks/

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kozhevnikov picture kozhevnikov  ·  6Comments

dblooman picture dblooman  ·  7Comments

jan-molak picture jan-molak  ·  4Comments

jfstephe picture jfstephe  ·  4Comments

protoman92 picture protoman92  ·  3Comments