I want to have two different scenarios in the same feature.
The thing is that Scenario 1 needs to be executed before Scenario 2. I have seen that this can be achieved through cucumber Hooks but when digging in the explanations, there's no concrete cucumber implementation in the examples I have found.
How can I get Scenario 1 executed before Scenario 2?
The feature file is like this:
#Events #InsertExhPlan #DelExhPln
Feature: Insert an Exh Plan and then delete it
#InsertExhPlan
Scenario: Add a new ExhPlan
Given I login as admin
And I go to automated test
When I go to ExhPlan section
And Insert a new exh plan
Then The exh plan is listed
#DeleteExhPlan
Scenario: Delete an Exh Plan
Given I login as admin
And Open the automatized tests edition
When I go to the exh plan section
And The new exh plan is deleted
Then The new exhibitor plan is deleted
The Hooks file is:
package com.barrabes.utilities;
import cucumber.api.java.After;
import cucumber.api.java.Before;
import static com.aura.steps.rest.ParentRestStep.logger;
public class Hooks {
#Before(order=1)
public void beforeScenario(){
logger.info("================This will run before every Scenario================");
}
#Before(order=0)
public void beforeScenarioStart(){
logger.info("-----------------Start of Scenario-----------------");
}
#After(order=0)
public void afterScenarioFinish(){
logger.info("-----------------End of Scenario-----------------");
}
#After(order=1)
public void afterScenario(){
logger.info("================This will run after every Scenario================");
}
}
The order is now as it should be but I don't see how does the Hooks file control exection order.
You don't use Hooks for that purpose. Hooks are used for code that you need to run before and/or after tests, and/or before and/of after test suites; not to control the order of features and/or scenarios.
Cucumber scenarios are executed top to bottom. For the example you showed there, Scenario: Add a new ExhPlan will execute before Scenario: Delete an Exh Plan if you pass the tag #Events in the test runner. Also, you should not have the scenario tags at the feature level. So, you should remove #InsertExhPlan and #DelExhPln at the Feature level. Alternatively, you could pass a comma-separated list of scenario tags to the test runner in the order you want. For example, if you need to run scenario 2 before scenario 1, you would pass the tags for the corresponding scenarios in the order you wish them to be executed. Moreover, you can do this as well from your CI environment. For example, you can have Jenkins jobs that execute the tasks in a specific order by passing the scenario tags in that order. And, if you wish to be run in the default order, simply you can pass the feature tag.
About Hooks, this should be for code that needs to be run for all features and scenarios. For specific stuff you need to run for a particular feature, you need to use Background in the Cucumber file. Background block is run before each scenario in a given feature file.
Related
Assuming that I have a Cucumber feature tagged #api
#api
Feature: BankID authentication
Scenario Outline: Successful authentication of user using BankID
Given the initial flow start URLĀ
When I enter that "<url>" into my browser
...
and steps for execution as below:
public class ApiSteps implements En {
public ApiSteps (ABCinjected abcInjected) {
Given("^the initial flow start URLĀ $", () -> {});
When("^I enter that \"([^\"]*)\" into my browser$", abcInjected::navigateToAuthenticationPage);
...
}
Even if I define this feature not to be executed by specifying different Cucumber tags or explicitly specifying tags = {"not #api"} , although steps themselves are not executed per se, Picocontainer still creates and injects instance of ABCinjected class, which is undesirable. Is it possible to control this behavior? I assume if feature is tagged as not to be executed and related scenario/steps are ignored, consecutively DI should not happen.
I got response from Cucumber contributor on Github:
When using lamda steddefs the class has to be instantiated to register
the steps. And we would need to know the steps defined by the class to
determine if we should instantiate it. This is a dead lock of
requirements.
Another recommendation is to set different packages for steps (api, units etc) and set different glue on runtime.
https://github.com/cucumber/cucumber-jvm/issues/1672
I have three different feature files which hold different test scenarios: configA.feature, configB.feature, common.feature.
In the steps file I have two tagged before hooks, one for each config (A/B):
#Before("#ConfigA")
public void configA() {
//some settings
}
#Before("#ConfigB")
public void configB() {
//some settings
}
These two configs are mutually exclusive, so only one should be executed for any particular scenario execution as the second would overwrite setting done by the first.
What I want to achieve is to be able to run scenarios as follows:
configA.feature with the ConfigA hook executed
configB.feature with the ConfigB hook executed
common.feature with the ConfigA hook executed
common.feature with the ConfigB hook executed
I've tried annotating the features in the feature files as:
configA with #ConfigA
configB with #ConfigB
common with both #ConfigA #ConfigB
but this results in common.feature being always executed with both of the before hooks at the same time.
As I'm using a JUnit wrapper with Cucumber runner I've also tried creating separate test classes with #CucumberOptions.tags specified, but this didn't work for me either.
Is, what I'm trying to do, even possible with cucumber? If so then how can I achieve this?
I want to change the scenario status for known issues into the After hook.
Something like:
#After
public void afterScenario(Scenario scenario) {
if(scenario.isFailed() && scenario.getSourceTagNames().contains("knownIssue")){
//scenario.add(Result.SKIPPED)
}
}
The idea is tests, which fail because of known bug to be skipped into the test report.
Thanks,
Nayden
You can annotate the scenario with #KnownIssue and then run cucumber with --tags "not #KnownIssue" or its #CucumberOptions equivalent.
it is your test execution engine that is responsible for this aspect, aka TestNG, JUnit.
So the question is: How to change Test Execution Status Programmatically? Here is one explained. You can hook in to the Test Execution Engine either by the way explained in the artcicle or from your method - what is important - you have to work with the Test Execution Engine and not Cucumber.
Gherkin with qaf supports what you are looking for. With qaf
you can achieve it by test ng after method invocation listener.
In addition you also can add meta-data at step level and handle it in onFailure method of step listener to modify exception to Skip exception depending on step meta data. Which automatically skips tests where that step is called and failed.
I am using Serenity with BDD and need to perform a teardown step that must get executed after completion of each Scenario. Also, this teardown step should not be visible to report as it is technical thing and nothing to do with behavior to be exposed as part of cucumber such as releasing few expensive resource that got
I used cucumber's #After annotation which is working as expected, but the problem is now this step is also shown in my Report which I don't want to be visible.
Could someone please suggest me a solution that allows me to perform teardown step that gets executed per scenario but should not be added as step in my Serenity Report.
Current Solution I have is which does not satisfy my need:
Step Definition Class has following method:
#After
public void tearDown() {
systemAction.deleteCostlyResource(id);
}
but #After annotation makes it a candidate for Reporting Step.
If you are using Dependency Injection, you could have your DI framework teardown the resources at the end of the scenarios?
For instance, if you are using Spring:
If the "costly resource" is a class that you yourself have created, mark it with:
#Component
#Scope("cucumber-glue")
If the "costly resource" is not a class you created, but provided by a framework or whatever, you can register it as a bean in your spring (test)configuration and mark it with a "destroy method".
For example, to register Selenium WebDriver using annotation based configuration and making sure to quit after each Scenario, mark it with:
#Bean(destroyMethod = "quit")
In this example, quit() is WebDriver's method to quit(). In your situation, call "costly resource's" quit method, or equivalent thereof.
I have a Behat FeatureContext with some custom steps, and I'd like to do the following:
Initialize a variable/array/object when the test suite starts,
Have that variable/array/object available within the scope of each Scenario in the test suite,
Have values stored in the variable/array/object updated after all of the steps in each Scenario execute,
When test suite execution is complete, persist the values (writing out to a log file would be perfect).
Can this be done, and how would you go about structuring this? I'm attempting to do this using #BeforeSuite, #BeforeScenario and #AfterScenario hooks but have not yet been successful (my OOP is a little rusty).