Cucumber Tags Example

Introduction

In this tutorial you will see how to work on Cucumber Tags. Tags in Cucumber are great ways to organize your features and scenarios. It is pretty much simple when you have one, two, or maybe five scenarios in a feature file. However, in real life project, for each feature, you may have 20, 30, or may be more number of scenarios in a single feature file. They may represent different purpose (Smoke test/Regression test), different prospectives (Dev/Sit/Uat), different status (Ready for execution/Work in progress), etc. Now the question is how to manage execution for such a big file?

For this, Cucumber has provided a way to organize feature file’s scenario execution by using tags in feature file. You can define each scenario with a useful tag. Later, in the cucumber runner file, you can decide which specific tag (scenario(s)) you want Cucumber to execute. Tag starts with “@”. After “@” you can have any relevant text to define a tag.

Prerequisites

Java at least 8, Maven 3.6.3, Gradle 6.1.1 – 6.7.1, Cucumber 5.3.0/6.10.1, Junit 5.6.0/5.8.0-M1

Project Setup

Create gradle or maven based project in your favorite IDE or tool. The name of the project is cucumber-tags. I am using here Junit 5 so I need to use Junit Vintage engine as Cucumber is compatible with Junit 4 only as of now.

Remember feature file, Java classes are written into src/test/resources or src/test/java folder.

If you are creating gradle based project then you can use below build.gradle script.

plugins {
    id 'java-library'
}

sourceCompatibility = 12
targetCompatibility = 12

repositories {
    jcenter()    
}

dependencies {
    implementation('io.cucumber:cucumber-java:5.3.0') /6.10.1
	implementation('io.cucumber:cucumber-junit:5.3.0') /6.10.1
	testImplementation('org.junit.jupiter:junit-jupiter-engine:5.6.0') /5.8.0-M1
	testImplementation('org.junit.vintage:junit-vintage-engine:5.6.0') /5.8.0-M1
}

If you are creating maven based project then you can use below pom.xml file:

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.roytuts</groupId>
	<artifactId>cucumber-tags</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<maven.compiler.source>12</maven.compiler.source>
		<maven.compiler.target>12</maven.compiler.target>
	</properties>

	<dependencies>
		<dependency>
			<groupId>io.cucumber</groupId>
			<artifactId>cucumber-java</artifactId>
			<version>6.10.1</version>
		</dependency>

		<dependency>
			<groupId>io.cucumber</groupId>
			<artifactId>cucumber-junit</artifactId>
			<version>6.10.1</version>
		</dependency>

		<dependency>
			<groupId>org.junit.jupiter</groupId>
			<artifactId>junit-jupiter-engine</artifactId>
			<version>5.8.0-M1</version>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>org.junit.vintage</groupId>
			<artifactId>junit-vintage-engine</artifactId>
			<version>5.8.0-M1</version>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.8.1</version>
			</plugin>
		</plugins>
	</build>
</project>

Feature File

Feature file, is a language agnostic, where you write steps for software features to group scenarios using Gherkin language. More information can be found in the documentation.

In the below feature file, I have put several tags as you see, for example, @Org, @Net, @DEV etc. The names of the tags are given as per our choice.

A feature or scenario can have as many tags as you like. Separate them with spaces.

Tags can be placed above the following Gherkin elements:

  • Feature
  • Scenario
  • Scenario Outline
  • Examples

The following feature is written into cucumberTag.feature file under src/test/resources/cuke/features folder.

@Org @Net
Feature: Testing for login page

@DEV
Scenario Outline: Unsuccessful login

	Given I want to use the browser Firefox
	When I set the username to "<username>"
	When I set the password to "<password>"
	When I login to CosmicComix
	Then I see the error message "<message>"
	And I am on the login page

	@Regression
	Examples:
	|	username		|	password		|		message		|
	|	testuser1 		|					|	Please provide a password.	|
	|					|	testuser1		|	Please provide a username.	|
	|	testuser		|	testuser		|	That username does not match anything in our records.		|
	|	testuser1		|	testuser2		|	The password provided does not match the username entered.	|

@SIT
Scenario Outline: Successful login

	Given I want to use the browser "<browser>"
	When I set the username to testuser1
	And I set the password to testuser1
	When I login to CosmicComix
	Then I am on the launcher page

	@Regression
	Examples:
			|	    browser	 |
			|	    Firefox	 |
			|	    Chrome       |
			|     InternetExplorer   |
	@Smoke
	Examples:
			|	browser		|
			|	Firefox		|

@UAT
Scenario Outline: Login to Facebook

	Given user navigates to Facebook
	When I enter Username as "<username>" and Password as "<password>"
	Then login should be unsuccessful
	Then the user should be redirected to login retry
	
	Examples:
	| username  | password  | 
	| username1 | password1 | 
	| username2 | password2 |

The above file is to give you ideas how to work on Cucumber tags and you can have different features based on scenarios for your projects.

Runner File

The runner class is required to execute your feature file and step definition file which you will see later.

The class I have to configure mainly using @RunWith and @CucumberOptions.

The @RunWith annotation tells to run the class with Cucumber framework. The @CucumberOptions annotation has different options as given below:

  • features – location of the feature file
  • glue – the package where the step definition class will be written
  • monochrome – you want the output in console in human readable format
  • plugin – in what format and where you want the generated output file
package cucumber.tags;

import org.junit.runner.RunWith;

import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;

@RunWith(Cucumber.class)
@CucumberOptions(features = "classpath:cuke/features/cucumberTag.feature", glue = "cucumber.tags.steps", monochrome = true, plugin = {
		"pretty", "html:target/cucumber", "json:target/Cucumber.json",
		"junit:target/Cucumber.xml" })
public class CukeTagRunner {

}

For version cucumber 6.10.1 and junit 5.8.0-M1, you need to change the above class as below:

package cucumber.tags;

import org.junit.runner.RunWith;

import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;

@RunWith(Cucumber.class)
@CucumberOptions(features = "classpath:cuke/features/cucumberTag.feature", glue = "cucumber.tags.steps", monochrome = true, plugin = {
		"pretty", "html:target/reports/cucumber-html-report.html", "json:target/reports/cucumber.json",
		"junit:target/Cucumber.xml" }, tags = "@SIT and not @Smoke")
public class CukeTagRunner {

}

Step Definition

The step definition file is language dependent and here I am using Java language to write our step definition file.

Running the above CukeTagRunner file will give you the following step definition in the eclipse console. If you want you may also write yourself such step definition to match the steps written in feature file.

In the below you see that the methods have been generated from the feature file and you also see that each of the method throws PendingException() because I have not yet implemented any step defined in feature file.

You will find many repeated methods, so I will discard the duplicate methods and accordingly I will adjust to match the steps defined in the feature file.

@Given("I want to use the browser Firefox")
public void i_want_to_use_the_browser_Firefox() {
    // Write code here that turns the phrase above into concrete actions
    throw new io.cucumber.java.PendingException();
}

@When("I set the username to {string}")
public void i_set_the_username_to(String string) {
    // Write code here that turns the phrase above into concrete actions
    throw new io.cucumber.java.PendingException();
}

@When("I set the password to {string}")
public void i_set_the_password_to(String string) {
    // Write code here that turns the phrase above into concrete actions
    throw new io.cucumber.java.PendingException();
}

@When("I login to CosmicComix")
public void i_login_to_CosmicComix() {
    // Write code here that turns the phrase above into concrete actions
    throw new io.cucumber.java.PendingException();
}

@Then("I see the error message {string}")
public void i_see_the_error_message(String string) {
    // Write code here that turns the phrase above into concrete actions
    throw new io.cucumber.java.PendingException();
}

@Then("I am on the login page")
public void i_am_on_the_login_page() {
    // Write code here that turns the phrase above into concrete actions
    throw new io.cucumber.java.PendingException();
}

@Given("I want to use the browser Firefox")
public void i_want_to_use_the_browser_Firefox() {
    // Write code here that turns the phrase above into concrete actions
    throw new io.cucumber.java.PendingException();
}

@When("I set the username to {string}")
public void i_set_the_username_to(String string) {
    // Write code here that turns the phrase above into concrete actions
    throw new io.cucumber.java.PendingException();
}

@When("I set the password to {string}")
public void i_set_the_password_to(String string) {
    // Write code here that turns the phrase above into concrete actions
    throw new io.cucumber.java.PendingException();
}

@When("I login to CosmicComix")
public void i_login_to_CosmicComix() {
    // Write code here that turns the phrase above into concrete actions
    throw new io.cucumber.java.PendingException();
}

@Then("I see the error message {string}")
public void i_see_the_error_message(String string) {
    // Write code here that turns the phrase above into concrete actions
    throw new io.cucumber.java.PendingException();
}

... and so on

Now after discarding the duplicate methods I have put the required methods into CukeTagStepDefinition.java file and removed the PendingException() to denote that these methods are no more pending.

The final class is given below:

package cucumber.tags.steps;

import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;

public class CukeTagStepDefinition {

	@Given("I want to use the browser Firefox")
	public void i_want_to_use_the_browser_Firefox() {
	}

	@When("I set the username to {string}")
	public void i_set_the_username_to(String string) {
	}

	@When("I set the password to {string}")
	public void i_set_the_password_to(String string) {
	}

	@When("I login to CosmicComix")
	public void i_login_to_CosmicComix() {
	}

	@Then("I see the error message {string}")
	public void i_see_the_error_message(String string) {
	}

	@Then("I am on the login page")
	public void i_am_on_the_login_page() {
	}

	@Given("I want to use the browser {string}")
	public void i_want_to_use_the_browser(String string) {
	}

	@When("I set the username to testuser1")
	public void i_set_the_username_to_testuser1() {
	}

	@When("I set the password to testuser1")
	public void i_set_the_password_to_testuser1() {
	}

	@Then("I am on the launcher page")
	public void i_am_on_the_launcher_page() {
	}

	@Given("user navigates to Facebook")
	public void user_navigates_to_Facebook() {
	}

	@When("I enter Username as {string} and Password as {string}")
	public void i_enter_Username_as_and_Password_as(String string, String string2) {
	}

	@Then("login should be unsuccessful")
	public void login_should_be_unsuccessful() {
	}

	@Then("the user should be redirected to login retry")
	public void the_user_should_be_redirected_to_login_retry() {
	}

}

In the above class I have not written anything inside the methods. Ideally you need to write what you want to perform, for example, you can use Selenium web driver to automate your testing.

Testing the Application

Now running the CukeTagRunner class will pass all the test cases as shown below from he console log:

10 Scenarios (10 passed)
52 Steps (52 passed)
0m1.437s

If you want to see the pretty format report then under the build (gradle project) folder you can find the directories reports/tests/test and open the file index.html in a browser to see the test report.

Make sure you build the project using command line tool by executing the command gradle build or gradlew build before looking out for the report.

cucumber tags example

Running tests against Tags

So in the above wIhave executed all test cases but what if you want to execute only particular test scenarios or steps or examples. Then you have to execute the tag(s) only. For example you may want to execute some tests in development environment, then you can execute the scenario which is tagged with @DEV. If you want to execute regression tests then you have to execute the steps with @Regression tag and so on.

Let’s say you want to execute the @DEV tag. Therefore, you have to slightly update the CukeTagRunner class. You need to add @DEV tag which you want to execute. So add this tag using tags option in the @CucumberOptions(). The CukeTagRunner class now looks as follows:

@RunWith(Cucumber.class)
@CucumberOptions(features = "classpath:cuke/features/cucumberTag.feature", glue = "cucumber.tags.steps", monochrome = true, plugin = {
		"pretty", "html:target/cucumber", "json:target/Cucumber.json",
		"junit:target/Cucumber.xml" }, tags = { "@DEV" })
public class CukeTagRunner {

}

Now executing the CukeTagRunner class will give you the following output in the console:

4 Scenarios (4 passed)
24 Steps (24 passed)
0m1.319s

And report will give you:

cucumber tags example

Now if you want to execute multiple tags at a time then, you can use multiple tags in the following way:

tags = { "@SIT and not @Smoke" }

So the above tag tells that execute scenarios tagged with @SIT and exclude the steps having tagged with @Smoke.

Executing the runner class you will get below output:

3 Scenarios (3 passed)
15 Steps (15 passed)
0m1.713s

The report will give you the following output:

cucumber tags example

Depending on your version of gradle, junit and cucumber you will get different formats of the output.

For the version gradle 6.7.1, junit 6.10.1 and cucumber 5.8.0-M1, you will get below format:

cucumber tags example

That’s all about cucumber tags examples.

Source Code

Download

Leave a Reply

Your email address will not be published. Required fields are marked *