Join us on :

Table of content

Cucumber Tags with Selenium

Most of the times, In cucumber projects, there will be many scenarios in a single features files. We should be creating feature files based on the application feature or based on the functionality.

We try to keep all the related scenarios within the same feature file and this is one of the reason why we end up having more scenarios in the cucumber feature file.

For Example, you have got many different feature files which cover all the different functionality of the application. Now there can be a certain situation in the project where you like to execute just a SmokeTests or Sanity or maybe Nightly Regressions to ensure nothing got broken but at the same, you might not be having all these in the same file.

If you remember, we had a similar situation with TestNG test cases, there we took the help of TestNG Groups, In cucumber, we have similar feature called Tags to group the features.

Tag starts with "@", followed by tag names like sanity test or smoke test or anything you wish, our tag will look like @SanityTests just above the scenario keyword.

One scenario can have more than one tag separated by space


@SanityTests
Scenario: Search Google for Chercher Tech
  Given There is opened "Chrome browser" 
  Then I search "Chercher Tech" in searchbar

@SanityTests @Regression
Scenario: Search Bing for Chercher Tech
  Given There is opened "Chrome browser" 
  Then I search "Chercher Tech" in searchbar  

Now we have to specify the tag name which wants to run in the cucumber runner using tags = {"@SanityTests"} in CucumberOptions


package runner;

import org.junit.runner.RunWith;
import cucumber.api.CucumberOptions;
import cucumber.api.junit.Cucumber;

@RunWith(Cucumber.class)
@CucumberOptions(features= "features", 
				glue= {"testDefinitions"},
				tags = {"SanityTests"})
public class TestRunner {

}	

Below is the Feature file which contains different tags

Combining tags Using AND & OR :

Sometimes you might need to run more than one tags at a time, in such cases, you can use AND & OR to combine the cucumber tags to run the feature files.

OR or Comma: Runs the scenario if it has at least one give tag, there are separated with comma, all the tags will be include in one double quotes like {"Sanity, smoke, regression"}


@RunWith(Cucumber.class)
@CucumberOptions(features= "features", 
				glue= {"testDefinitions"},
				tags = {"SanityTests, SmokeTests"})
public class TestRunner {

}	

AND or Quotes: Runs the scenario if it has all the given tags, all the tags are separated with double quotes {"Sanity", "smoke", "regression"}


@RunWith(Cucumber.class)
@CucumberOptions(features= "features", 
				glue= {"testDefinitions"},
				tags = {"SanityTests", "SmokeTests"})
public class TestRunner {

}	

How to Ignore Cucumber Tests :

Sometimes you might need to skip tags in cucumber BDD, you can use a special Character ~ to skip the tags. This also work both for Scenarios and Features, this can also works along with AND or OR.


@RunWith(Cucumber.class)
@CucumberOptions(features= "features", 
				glue= {"testDefinitions"},
				tags = {"SanityTests", "~SmokeTests"})
public class TestRunner {

}	

You make all the non tagged scenarios to run by disabling the tagged scenarios using ~ will all tags in Runner.

Hooks in Cucumber

Hooks allow us to perform actions at various points in the cucumber test cycle.

@Before hooks will be run before the first step of each scenario. They will run in the same order of which they are registered.

@After hooks will be run after the last step of each scenario, even when there are failing, undefined, pending or skipped steps. They will run in the opposite order of which they are registered.

Cucumber supports only two hooks (Before & After) which works at the start and the end of the test scenario.

When using hooks :

You can use hooks to run before/after each scenario, a group of scenarios according to the tags, all the scenarios in a feature or all the scenarios of your project. They will run before the first step of your scenario, like the background, but it won’t need any step in your feature file.

You just need to define hooks, no need to associate the hooks, cucumber takes care of associating. I have Hook file in steps definition folder

Consider below cucumber feature file.


Feature: Sample test
  Search Chercher Tech in Google and click the first result

	Scenario: Search Google for ChercherTech
	  Given There is opened Google
	  Then I search ChercherTech in searchbar 

Hooke file containing @Before and @After


import cucumber.api.java.After;
import cucumber.api.java.Before;

public class Hooks {
	
	@Before
    public void beforeScenario(){
        System.out.println("*************Before Scenario***********");
    }	
	
	@After
    public void afterScenario(){
        System.out.println("############After Scenario##########");
    }
}

Steps definition file


public class Steps_Sample {
	WebDriver driver;
	
	@Given("^There is opened Google$")
	public void there_is_opened_Google() throws Throwable {
		System.setProperty("webdriver.chrome.driver", "D:\\Eclipse progs\\driverserver\\chromedriver.exe");
		driver = new ChromeDriver();
		driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
		driver.get("https://google.com");
	}
	
	@Then("^I search ChercherTech in searchbar$")
	public void i_search_ChercherTech_in_searchbar() throws Throwable {
	    driver.findElement(By.name("q")).sendKeys("CherCherTech");
	}
}

No change in Test Runner file

After hook is that even the scenario fails, after hook will execute for sure. hooks-selenium-cucumber-bdd

Tagged Hooks in Cucumber :

Tagged Hooks are much like the scenario hooks but the only difference is that they are executed before and after the specified tag.

Let me put it in a simple way, Consider you have 10 different tags like sanity, Regression, Smoke tests, sometime you might want to check them with different urls or you may want to perform some special operation based on the tag, you can achieve such kind of things through the Tagged Hooks.

These Tagged hooks will be very specific to the particular tags, so these are not common for all scenarios

So basically, they can also be run in the following two ways:

  • Before ('tagName')
  • After ('tagName')
Let's write Feature file which has three scenarios with tags called @Sanity, @Smoke, @Regression respectively

Feature: Sample Cucumber JVM BDD test
  Search Chercher Tech in Google and click first result

	@Sanity
	Scenario: Search Google for Chercher Tech
	  Given Google is printed 

	@Smoke
	Scenario: Search Bing for Chercher Tech
	  Given Bing is printed 

	@Regression
	Scenario: Search DuckDuckGo for Chercher Tech
	  Given DuckDuckGo is printed  	  

Step definition file would look like


public class Steps_Sample {
	@Given("^Google is printed$")
	public void google_is_printed() throws Throwable {
	    System.out.println("Google");
	}

	@Given("^Bing is printed$")
	public void bing_is_printed() throws Throwable {
		System.out.println("Bing");
	}

	@Given("^DuckDuckGo is printed$")
	public void duckduckgo_is_printed() throws Throwable {
		System.out.println("DuckDuckGo");
	}
} 	  

Hooks file name Hooks.java


package testDefinitions;

import cucumber.api.java.After;
import cucumber.api.java.Before;

public class Hooks {
	
	@Before
    public void beforeScenario(){
        System.out.println("*************Before Scenario***********");
    }	
	@After
    public void afterScenario(){
        System.out.println("############After Scenario##########");
    }
	@Before("@Sanity")
    public void beforeGoogle(){
        System.out.println("*******before Google*******");
    }	
	@Before("@Smoke")
    public void beforeBing(){
        System.out.println("*********before Bing*******");
    }	
	@Before("@Regression")
    public void beforeDuckDuckGO(){
		System.out.println("*********before DuckDuckGO*******");
    }
	@After("@Sanity")
    public void afterGoogle(){
        System.out.println("$$$$$$$$$$$ After Google $$$$$$$$$$");   
    }	
	@After("@Smoke")
    public void afterBing(){
		System.out.println("$$$$$$$$$$$ After Bing $$$$$$$$$$");   
    }	
	@After("@Regression")
    public void afterDuckDuckGo(){
        System.out.println("$$$$$$$$$$$ After DuckDuckGo $$$$$$$$$$");    
    }	
}	  

There is no change to Test Runner File

Hooks file name Hooks.java


import org.junit.runner.RunWith;
import cucumber.api.CucumberOptions;
import cucumber.api.junit.Cucumber;

@RunWith(Cucumber.class)
@CucumberOptions(features= "features", 
				glue= {"testDefinitions"})
public class TestRunner {

}	  

Common Tagged Hooks :

Sometime in your scenarios, there could be common pre and post steps, In such cases, you can combine them in hooks.

the common Hooks file may look like below


package testDefinitions;

import cucumber.api.java.After;
import cucumber.api.java.Before;

public class Hooks {
	
	@Before("@Sanity, @Smoke")
    public void beforeSanitySmoke(){
        System.out.println("*******before SanitySmoke*******");
    }		
	@Before("@Regression")
    public void beforeDuckDuckGO(){
		System.out.println("*********before DuckDuckGO*******");
    }
		
	@After("@Sanity, @Smoke")
    public void afterSanitySmoke(){
		System.out.println("$$$$$$$$$$$ After SanitySmoke $$$$$$$$$$");   
    }	
	@After("@Regression")
    public void afterDuckDuckGo(){
        System.out.println("$$$$$$$$$$$ After DuckDuckGo $$$$$$$$$$");    
    }	
}	  

Order of execution of hooks :

If you have worked with the TestNG, you might be familiar with the priority of test, basically, priority make the execution order of TestNg script

We can achieve the execution order using the value in the hooks in cucumber, the value parameter decides on sequence cucumber should run the tests.

Set the Order for Cucumber Hooks :

  • @Before(order = intValue) : runs from lowest to highest, means value 0 would run first and 1 will be after 0.
  • @After(order = intValue) : runs from highest to lowest, means opposite of @Before. Value 1 will run first and 0 would be after 1.

package utilities;

import cucumber.api.java.After;
import cucumber.api.java.Before;

public class Hooks {
	
	@Before(order=1)
    public void beforeScenarioOne(){
        System.out.println("****** beforeScenarioOne *******");
    }	
	@Before(order=0)
    public void beforeScenarioTwo(){
        System.out.println("****** beforeScenarioTwo *******");
    }	
	
	@After(order=0)
    public void afterScenarioOne(){
        System.out.println("****** afterScenarioOne *******");
    }	
	@After(order=1)
    public void afterScenarioTwo(){
        System.out.println("****** afterScenarioTwo *******");
    }	
}	  

About Author

Article is written by Pavan (a) KarthiQ. Well, I am serving notice period in an MNC, Bangalore. I thought to enrich every person knowledge a little, I always have a feeling, when we teach something, we will learn more than what you know. Knowledge is the only thing that doubles when you spend it.

I have also created the reporter for Protractor Jasmine. Use for your projects without any hesitation

Comment / Suggestion Section
Point our Mistakes and Post Your Suggestions