In BDD, users (business analysts, product owners) first write scenarios or acceptance tests that describe the behavior of the system from the customer’s perspective, for review and sign-off by the product owners before developers write their code.
This is to bridge the gap between the test cases written by QA and BRD/FD written by Business analyst. Earlier test cases were written on the basis of big document called BRD.
Some requirements can be skipped and it becomes difficult to trace requirements and test cases i.e. which test case is for which requirement.
Cucumber has made it very easy to track all requirements and test cases.
Cucumber is best suited in agile environment where there is always a user story to start with.
User stories are short, simple descriptions of a feature told from the perspective of the person who desires the new capability, usually a user or customer of the system. They typically follow a simple template:
Template: As a < type of user >, I want < some goal > so that < some reason >.
For Example:
As a user when I login into Facebook, home page should appear.
As a user when I login into Facebook, home page should appear.
As such, they strongly shift the focus from writing about features to discussing them. In fact, these discussions are more important than the text they have written.
Now above story will be used in cucumber that will be called as a feature.
It is helpful to involve business stakeholders who can’t easily read code.
Cucumber focuses on end-user experience.
Style of writing tests makes it easier to reuse the code in the tests.
Quick and easy set up as well as execution.
One need to know the below given description of what a feature is in order to understand cucumber. Example of feature is as shown below:
Feature: Login Functionality Feature
Scenario: Login Functionality
Given user navigates to SOFTWARETETINGHELP.COM
When user logs in using Username as “USER”
And password as “password”
Then login should be successful
And Home page should be displayed
Explanation for the above terms:
Given: As mentioned above, given specifies the pre-conditions. It is basically a known state.
When: This is used when some action is to be performed. As in above example we have seen when the user tries to log in using username and password, it becomes an action.
Then: The expected outcome or result should be placed here. For Instance: when ‘verify the login’ is successful it will navigate to ‘successful’ page.
Background: Whenever any step is required to perform in each scenario then those steps needs to be placed in Background. For Instance: If user needs to clear database before each scenario then those steps can be put in background.
And: And is used to combine two or more same types of actions.
Example of Background:
Background:
Given user logged in as database’s administrator.
And all the junk values are cleared.
First, we will setup the project in eclipse by following the steps as mentioned below:
Eclipse plugin for cucumber.
Natural is a collection of Eclipse plugins to enable rich smart editing of acceptance tests using natural language definition files. It currently supports Cucumber and JBehave syntax.Make maven project to get dependencies in project.
Select maven project in eclipse.
Get quick start as archetype.
Name it as cucumber-maven.
We will be asked about version number and properties configuration but we can go with the defaults. The following structure with pom.xml, App.java and AppTest.java (which follows Maven’s Standard Directory Layout) will be created.
It will have the project structure as shown in below image:
Now that we have a bare-bones Maven project we can start doing Behavior Driven Development by creating a failing acceptance test. We will delete the by default generated App.java and AppTest.java files.
It takes a moment to update pom.xml to add required dependencies and configure the compiler as below below:
<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.javabykiran.bdd</groupId>
<artifactId>cucumber-maven</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>cucumber-maven</name>
<url>http://maven.apache.org </url>
<properties>
<project.build.sourceEncoding>
UTF-8
</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-java</artifactId>
<version>1.1.8</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-junit</artifactId>
<version>1.1.8</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>
maven-compiler-plugin
</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
In the above pom.xml file:
dependencies tag - We use Cucumber and JUnit so Maven will download the required jars.
plugin tag – It is a java compiler configuration.
Now project structure will look as shown below:
If we see an error as shown below go to problems window and see what problems we have in our project:
So follow the steps as mentioned below and update maven project due to which errors will be removed. Create ‘feature’ file as shown below in folder ‘resources/ cucumber’ in ‘test’ folder under ‘src’ and save it as “calculator.feature”.
1 Feature: Calculator
2 As a user
3 I want to use a calculator
4 So that I don’t need to calculate myself
5 Scenario: Add two numbers
6 Given I have a calculator
7 When I add 1 and 3
8 Then the result should be
Below is the explanation of the above created ‘feature’ file:
Line 1 – Let Cucumber know that this is a feature file.
Line 2-4 – It is a User story which is not executed but we add it for clarity. Line 6 – A new scenario is started.
Line 7-8 – They are steps wherein the scenario is executed.
Now our project structure will be something like this as shown in below image:
In order to run the feature, we will create a runner class ‘RunCalculatorTest’ which contains ‘Cucumber’ execution parameters.
package com.javabykiran.bdd.runner;
import cucumber.api.CucumberOptions;
import cucumber.api.junit.Cucumber;
import org.junit.runner.RunWith;
1) @RunWith(Cucumber.class)
2) @CucumberOptions(
format = { “pretty”, “html:target/cucumber” },
glue = “com.javabykiran.bdd.steps”,
features = “classpath:cucumber/calculator.feature”)
public class RunCalculatorTest
{
}
In above program line number:
We want Cucumber to run this test and
Passing the Cucumber options i.e. output formatting and location of the feature file.
Skip below steps if no errors are encountered:
If any compilation issues occurs, go ahead with trouble shooting as shown below. Hover the mouse on the error and fix it.
Now our structure will look as shown below:
Run as >> Maven clean >> maven test [perform this repeatedly if the build fails. Here ‘clean’ is used for deleting all compiled code].
Now the below shown data will appear in the console.
[INFO] Scanning for projects... [INFO]
[INFO] ------------------------------------------------------
[INFO] Building cucumber-maven 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ cucumber-maven ---
[INFO] Using ‘UTF-8’ encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory E:\batch\selNote\cucumber-maven\src\main\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ cucumber-maven ---
[INFO] Nothing to compile - all classes are up to date [INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ cucumber-maven ---
[INFO] Using ‘UTF-8’ encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-test-Compile) @ cucumber-maven ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ cucumber-maven ---
[INFO] Surefire report directory: E:\batch\selNote\cucumber-maven\target\surefire-reports
--------------------------------------------------------------
T E S T S
--------------------------------------------------------------
Running com.javabykiran.bdd.runner.RunCalculatorTest
Feature: Calculator
As a user
I want to use a calculator
So that I don’t need to calculate myself
Scenario: Add two numbers
[90m# cucumber/calculator.feature:6[0m
[33mGiven [0m[33mI have a calculator[0m
[33mWhen [0m[33mI add 2 and 3[0m
[33mThen [0m[33mthe result should be 5[0m
1 Scenarios ([33m1 undefined[0m)
3 Steps ([33m3 undefined[0m)
0m0.000s
You can implement missing steps with the snippets below:
@Given(“^I have a calculator$”)
public void i_have_a_calculator() throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
@When(“^I add (\\d+) and (\\d+)$”)
public void i_add_and(int arg1, int arg2) throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
@Then(“^the result should be (\\d+)$”)
public void the_result_should_be(int arg1) throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
Tests run: 5, Failures: 0, Errors: 0, Skipped: 4, Time elapsed:
0.443 sec Results :
Tests run: 5, Failures: 0, Errors: 0, Skipped: 4
[INFO] -----------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] -----------------------------------------------------
[INFO] Total time: 2.381 s
[INFO] Finished at: 2017 08-13T01:06:25+05:30
[INFO] Final Memory: 9M/102M
[INFO] -----------------------------------------------------
We will get quite a lot of outputs but the most important thing is that Cucumber tells us about missing step definitions and provides skeletons for the implementation.
This proves to be a very useful feature as it gives us information about the missing code and helps with writing regular expressions. So let’s put these steps in ‘CalculatorSteps’:
package com.javabykiran.bdd.steps;
import cucumber.api.PendingException;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
public class Calculator Steps {
@Given(“^I have a calculator$”)
public void i_have_a_calculator() throws Throwable
{
// Write code here that turns the phrase above into concrete actions
// selenium code or any testing code
throw new PendingException();
}
@When(“^I add (\\d+) and (\\d+)$”)
public void i_add_and(intnum1, intnum2) throws Throwable
{
// Write code here that turns the phrase above into concrete actions
// selenium code or any testing code
throw new PendingException();
}
@Then(“^the result should be (\\d+)$”)
public void the_result_should_be(intnum1) throws Throwable
{
// Write code here that turns the phrase above into concrete actions
// selenium code or any testing code
throw new PendingException();
}
}
Create a ‘calculator’ class for which we want to do the testing.
package com.javabykiran.bdd.calculator;
public class Calculator {
privateint result;
public void add(int num1, int num2) {
result = num1 + num2;
}
public int getResult() {
return result;
}
}
Now our project structure will look something like this.
Now we will be writing actual testing code in CalculatorSteps.java. We will modify the code which we have already created.
package com.javabykiran.bdd.steps;
import com.javabykiran.bdd.calculator.Calculator;
import cucumber.api.java.Before;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
public class CalculatorSteps {
private Calculator;
@Before
public void setUp() { // name can be changed
calculator = new Calculator();
}
@Given(“^I have a calculator$”)
public void i_have_a_calculator() throws Throwable {
// selenium code goes here
assertNotNull(calculator);
}
@When(“^I add (\\d+) and (\\d+)$”)
public void i_add_and(int num1, int num2) throws Throwable {
// selenium code goes here
calculator.add(num1, num2);
}
@Then(“^the result should be (\\d+)$”)
public void the_result_should_be(int result) throws Throwable {
// selenium code goes here
assertEquals(result, calculator.getResult());
}
}
Troubleshooting:
If compile time error occurs, then clean the project:
Project >> clean
Now when we run the tests,we should get successful results.
Now we can see output in console which will be scattered.
Console output problems:
If our console is not configured to display colored output from Cucumber we may see something that resembles a failed ascii-art like the one shown below.
Feature: Calculator
As a user
I want to use a calculator
So that I don’t need to calculate myself
Scenario: Add two numbers
_[90m# cucumber/calculator.feature:6_[0m
_[32mGiven _[0m_[32mI have a calculator_[0m
_[90m# Calcu- latorSteps.i_have_a_calculator()_[0m
_[32mWhen _[0m_[32mI add _[0m_[32m_[1m2_[0m_[32m and _[0m_ [32m_[1m3_[0m
_[90m# CalculatorSteps.i_add_and(int,int)_ [0m
_[32mThen _[0m_[32mthe result should be _[0m_[32m_[1m5_[0m
_[90m# CalculatorSteps.the_result_should_be(int)_[0m
1 Scenarios (_[32m1 passed_[0m)
3 Steps (_[32m3 passed_[0m) 0m0.114s
Tests run: 4, Failures: 0, Errors: 0, Skipped: 0, Time elapsed:
0.555 sec
Just modify ‘RunCalculatorTest’ formatting, so we can fix it by telling the runner to give the monochrome output as shown below:
@RunWith(Cucumber.class)
@CucumberOptions(
monochrome = true,
format = { “pretty”, “html:target/cucumber” },
glue = “com.javabykiran.bdd.steps”,
features = “classpath:cucumber/calculator.feature”
)
public class RunCalculatorTest {
}
Now we will see the out as shown below:
Running com.javabykiran.bdd.runner.RunCalculatorTest
Feature: Calculator
As a user
I want to use a calculator
So that I don’t need to calculate myself
Scenario: Add two numbers
# cucumber/calculator.feature:6
Given I have a calculator
# CalculatorSteps.i_have_a_calculator()
When I add 2 and 3
# CalculatorSteps.i_add_and(int,int)
Then the result should be 5
# CalculatorSteps.the_result_should_be(int)
1 Scenarios (1 passed)
3 Steps (3 passed)
0m0.118s
Tests run: 4, Failures: 0, Errors: 0, Skipped: 0, Time elapsed:
0.553 sec
Results :
Tests run: 4, Failures: 0, Errors: 0, Skipped: 0
When you run maven’s test goal:
It tries to locate tests in the project.
Using the default naming convention it finds ‘RunCalculatorTest’. This test is configured to run with Cucumber.
It will pick up the configuration options including output (format and monochrome), glue code (step implementations) and location of the feature file.
The feature file (written in a language called Gherkin) describes scenarios and their steps.
Scenarios are executed by mapping steps to methods annotated with ‘Given’, ‘When’ and ‘Then’ annotations, instantiating their classes and executing these methods.
Scenario and step execution can result in:
error – When there is an error or an exception during execution.
failure – When one of the assertions fails (AssertionError).
pending – When a step throws PendingException.
skip – When a step is not found or there is an exception in a previous step.
pass – When method execution becomes successful.
Now try failing test cases just by changing the feature file as shown below.
Instead of 5 I write 55 so that we will be able to see how many steps will pass and how many will fail.
Feature: Calculator
As a user
I want to use a calculator
So that I don’t need to calculate myself
Scenario: Add two numbers
Given I have a calculator
When I add 2 and 3
Then the result should be 44
Now after running this we will get the following output in console as shown below:
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.javabykiran.bdd.runner.RunCalculatorTest
Feature: Calculator
As a user
I want to use a calculator
So that I don’t need to calculate myself
Scenario: Add two numbers
# cucumber/calculator.feature:6
Given I have a calculator
# CalculatorSteps.i_have_a_calculator()
When I add 2 and 3
# CalculatorSteps.i_add_and(int,int)
Then the result should be 44
# CalculatorSteps.the_result_should_be(int)
java.lang.AssertionError: expected:<44> but was:<5>
at org.junit.Assert.fail(Assert.java:88)
at org.junit.Assert.failNotEquals(Assert.java:743)
at org.junit.Assert.assertEquals(Assert.java:118)
at org.junit.Assert.assertEquals(Assert.java:555)
at org.junit.Assert.assertEquals(Assert.java:542)
at com.javabykiran.bdd.steps.CalculatorSteps.the_result_should_be(CalculatorSteps.java:37)
at ?.Then the result should be 44(cucumber/calculator.feature:9)
1 Scenarios (1 failed)
3 Steps (1 failed, 2 passed)
0m0.124s
java.lang.AssertionError: expected:<44> but was:<5>
at org.junit.Assert.fail(Assert.java:88)
at org.junit.Assert.failNotEquals(Assert.java:743)
at org.junit.Assert.assertEquals(Assert.java:118)
at org.junit.Assert.assertEquals(Assert.java:555)
at org.junit.Assert.assertEquals(Assert.java:542)
at com.javabykiran.bdd.steps.CalculatorSteps.the_result_should_be(CalculatorSteps. java:37)
at ?.Then the result should be 44(cucumber/calculator.feature:9)
Tests run: 4, Failures: 2, Errors: 0, Skipped: 0, Time elapsed: 0.61 sec <<< FAILURE!
Then the result should be 44(Scenario: Add two numbers) Time elapsed: 0.012 sec <<< FAILURE!
java.lang.AssertionError: expected:<44> but was:<5>
at org.junit.Assert.fail(Assert.java:88)
at org.junit.Assert.failNotEquals(Assert.java:743)
at org.junit.Assert.assertEquals(Assert.java:118)
at org.junit.Assert.assertEquals(Assert.java:555)
at org.junit.Assert.assertEquals(Assert.java:542)
at com.javabykiran.bdd.steps.CalculatorSteps.the_result_should_be(CalculatorSteps. java:37)
at ?.Then the result should be 44(cucumber/calculator.feature:9)
Scenario: Add two numbers Time elapsed: 0.012 sec <<< FAILURE!
java.lang.AssertionError: expected:<44> but was:<5>
at org.junit.Assert.fail(Assert.java:88)
at org.junit.Assert.failNotEquals(Assert.java:743)
at org.junit.Assert.assertEquals(Assert.java:118)
at org.junit.Assert.assertEquals(Assert.java:555)
at org.junit.Assert.assertEquals(Assert.java:542)
at com.javabykiran.bdd.steps.CalculatorSteps.the_result_should_be(CalculatorSteps. java:37)
at ?.Then the result should be 44(cucumber/calculator.feature:9)
Results:
Failed tests: Then the result should be 44(Scenario: Add two numbers): expected:<44> but was:<5>
Scenario: Add two numbers: expected:<44> but was:<5>
Tests run: 4, Failures: 2, Errors: 0, Skipped: 0
Now we will see some live examples with multiple feature files.
Example of login page of website. In this example we will retain one feature file of calculator as well and add one more feature file. So that we will know how to run multiple feature files.
Directory structure will be as below with addition of new files.
In above directory I have added highlighted files and renamed RunALLTest.java as we want to use that class for running all feature files.
File: jbkfilesystem.feature-
Description: In this file we will be login with invalid credentials and test error message.
Feature: error message for jbk website
Scenario:
Java by kiran filesystem login with wrong uname and passwd error should displayed.
Given website is opened. - "https://javabykiran.com/javabykiranfiles/"
When wrong userid and password is supplied "kiran" and "kiran"
Then error message should be "×The supplied credentials are not valid."
Run as >> Maven clean >> maven test [perform this repeatedly if the build fails. Here ‘Clean’ is used for deleting all compiled code].
Now from console we can copy methods for our test steps. It will look like below.
File: JbksiteTestSteps.java
Description: it will have steps and we will write selenium code in this file also asserts.
If you can see from feature file we are sending dynamic parameters username as kiran and kiran as a password so you can change this whenever needed in feature file.
package com.javabykiran.bdd.steps;
import static org.testng.Assert.assertEquals;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
public class JbksiteTestSteps {
WebDriver driver;
@Given("^website is opened\\. - \"(.*?)\"$")
public void website_is_opened(String websiteName) throws Throwable {
driver = new FirefoxDriver();
driver.get(websiteName);
}
@When ("^wrong userid and password is supplied \"(.*?)\" and \"(.*?)\"$")
public void wrong_userid_and_password_is_supplied_and(String uname, String passwd) throws Throwable {
driver.findElement(By.id("login_form_user")).sendKeys(uname);
driver.findElement(By.id("login_form_pass")).sendKeys(passwd);
driver.findElement(By.name("submit")).click();
}
@Then ("^error message should be \"(.*?)\"$")
public void error_message_should_be(String expText) throws Throwable {
String actText = driver. findElement(By.xpath("//*[@id='login_error']")).getText();
assertEquals(actText, expText);
}
}
Meaning of below line:
@Given ("^website is opened\\. - \"(.*?)\"$")
Meaning of below line:
public void website_is_opened(String websiteName)
Below highlighted is how to give multiple feature files path. You can even mention folder name as well, below we have given folder name as cucumber as you can see in directory structure above:
Now you can run a test. Go to maven test.
Calculator test will run same as above and website test case will also start running.
So in total we ran 2 features file.
In console we can see results.
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.javabykiran.bdd.runner.RunAllTest
Feature: Calculator
As a user
I want to use a calculator
So that I don't need to calculate myself
Scenario: Add two numbers
# cucumber/calculator.feature:6 Given I have a calculator
# CalculatorSteps.i_have_a_calculator()
When I add 2 and 3
# CalculatorSteps.i_add_and(int,int)
Then the result should be 5
# CalculatorSteps.the_result_should_ be(int)
Feature: error message for jbk website
Scenario:
# cucumber/jbkfilesystem.feature:2
Java by kiran filesystem login with wrong uname and passwd error should displayed.
Given website is opened. - "https://javabykiran.com/javabykiranfiles/"
# JbksiteTestSteps.website_is_opened(String)
When wrong userid and password is supplied "kiran" and "kiran"
# JbksiteTestSteps.wrong_userid_and_password_ is_supplied_and(String,String)
Then error message should be "×The supplied credentials are not valid."
# JbksiteTestSteps.error_message_should_be(String)
2 Scenarios (2 passed)
6 Steps (6 passed)
0m18.173s
Tests run: 8, Failures: 0, Errors: 0, Skipped: 0, Time elapsed:
18.792 sec
Results :
Tests run: 8, Failures: 0, Errors: 0, Skipped: 0
[INFO] ------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------
[INFO] Total time: 45.606 s
[INFO] Finished at: 2018 01-13T21:04:11+05:30
[INFO] Final Memory: 22M/235M
[INFO] ------------------------------------------
Let’s say we want to test table then we can pass data from feature file as below. We will see feature file and test steps class.
Directory structure will be as below:
Feature: users on table of offline website
Scenario: Existing user Verification
Given open users page "https://www.javabykiran.com/demo"
When table is displayed
Then verify users data
| Name | Email |
| Java | java@jbk.com |
| By | by@jbk.com |
| Kiran | kiran@jbk.org |
package com.javabykiran.bdd.steps;
import cucumber.api.DataTable;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
public class TableTestSteps {
@Given("^open users page \"(.*?)\"$")
public void open_users_page(String arg1) throws Throwable {
// Write code here that turns the phrase above into concrete actions
//throw new PendingException();
}
@When("^table is displayed$")
public void table_is_displayed() throws Throwable {
// Write code here that turns the phrase above into concrete actions
//throw new PendingException();
}
@Then("^verify users data$")
public void verify_users_data(DataTable arg1) throws Throwable {
// Write code here that turns the phrase above into concrete actions
// For automatic transformation, change DataTable to one of
// List<YourType>, List<List<E>>, List<Map<K,V>> or Map<K,V>.
// E,K,V must be a scalar (String, Integer, Date, enum, etc)
//throw new PendingException();
}
}
This is how we can pass table data as well.
It’s very simple, only we need to tag some of scenarios as below.
And RunAllTest.java look like.
Observe output only smoketest tagging going to run.
If u want to exclude this tag just negate it. Like tags = {"~@SmokeTest"}
In the world of testing, you must have encountered the situations where you need to perform the prerequisite steps before testing any test scenario.
This prerequisite can be anything from:
Starting a webdriver
Setting up DB connections
Setting up test data
Setting up browser cookies
Navigating to certain page
or anything before the test
In the same way there are always after steps as well of the tests like:
Killing the webdriver
Closing DB connections
Clearing the test data
Clearing browser cookies
Logging out from the application
Printing reports or logs
Taking screenshots on error
or anything after the test
To handle these kind of situations, cucumber hooks are the best choice to use. Unlike TestNG An- notaions, cucumber supports only two hooks (Before & After) which works at the start and the end of the test scenario. As the name suggests, @before hook gets executed well before any other test scenario, and @after hook gets executed after executing the scenario.
Let’s do some easy and small example of Cucumber Hooks just to understand the concept. I will bring the intelligent usage of Hooks in my later tutorial series of Designing Framework with Cucumber.
Test Hooks with Single Scenario
Feature File
Feature: Test Hooks
Scenario: This scenario is to test hooks functionality
Given this is the first step
When this is the second step
Then this is the third step
Step Definitions
Package com.javabykira.bdd.stepDefinition;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
public class Hooks_Steps {
@Given("^this is the first step$")
public void This_Is_The_First_Step(){
System.out.println("This is the first step");
}
@When("^this is the second step$")
public void This_Is_The_Second_Step(){
System.out.println("This is the second step");
}
@Then("^this is the third step$")
public void This_Is_The_Third_Step(){
System.out.println("This is the third step");
}
}
Note: There is no logic used in the step definitions. Just printing the step summary log.
Hooks
package com.javabykira.bdd.utilities;
import cucumber.api.java.After;
import cucumber.api.java.Before;
public class Hooks {
@Before
public void beforeScenario(){
System.out.println("This will run before the Scenario");
}
@After
public void afterScenario(){
System.out.println("This will run after the Scenario");
}
}
Things to note:
An important thing to note about the after hook is that even in case of test fail, after hook will execute for sure.
Method name can be anything, need not to be beforeScenario() or afterScenario(). can also be named as setUp() and tearDown().
Make sure that the package import statement should be import cucumber.api.java.After; & import cucumber.api.java.Before;
Often people make mistake and import Junit Annotations, so be careful with this.
We will try understanding some basic questions on Cucumber.
Q.1) What are the differences between Jbehave and Cucumber?
Jbehave is Java based and Cucumber is Ruby based
Jbehave are based on stories while Cucumber is based on features
Q.2) What language is used for expressing scenario in feature file?
Q.3) What are 2 files required to execute a Cucumber Test Scenario?
Features
Step Definition
Q.4) What is Feature File? What Does Feature File consist of?
Feature
Scenario
Scenario Outline
Given
When
Then
Q.5) What is BDD Framework? What are benefits of BDD in Selenium?
- BDD is becoming widely accepted practice in agile software development, and Cucumber- JVM is a mainstream tool used to implement this practice in Java. Cucumber-JVM is based on Cucumber framework, widely used in Ruby on Rails world as well as in Java and .Net.
Cucumber-JVM allows developers, QA, and non-technical or business participants to write features and scenarios in a plain text file using Gherkin language with minimal restrictions about grammar in a typical Given, When, and Then structure.
The feature file is then supported by a step definition file, which implements automated steps to execute the scenarios written in a feature file. Apart from testing APIs with Cucumber-JVM, we can also test UI level tests by combining Selenium WebDriver.
Q.6) What is Profile in Cucumber?
- We can create Cucumber profiles to run specific features and step definitions.
We can use following command to execute a cucumber profile,
cucumber features -p <profile_name>
Ex: cucumber features -p regression
Q.7) What are Before, After, Beforestep and Afterstep Hooks?
- Before: execute before the feature file execution
After: executes after the feature file execution
BeforeStep: executes before the each step execution
AfterStep: executes after the each step execution
Q.8) What are Cucumber Tags? Why we use the Tags?
- Cucumber tags used to filter the scenarios. We can tag the scenarios and we can execute the scenarios based on tags, We can add tags to scenarios with @ We can use following command to execute a cucumber tagged scenarios.
cucumber features -t @<tag_name>
Ex: cucumber features -t @test
Q.9) What is Cucumber Dry Run?
- Cucumber dry run is used to compile cucumber feature files and stepDefinitions. If there is any compilations errors it will show when we use dry run.
Ex: Cucumber features –dry-run