Improve your testing effectivity by using Cucumber for Java software testing, absolutely built-in with Conduct-Pushed Growth (BDD). This information offers complete steps for mission setup, situation writing, step implementation, and reporting.
Introduction
Cucumber is a instrument that helps Conduct-Pushed Growth (BDD). A superb place to begin so as to study extra about BDD and Cucumber, are the Cucumber guides. BDD itself was launched by Dan North in 2006, you’ll be able to learn his weblog introducing BDD. Cucumber, nevertheless, is a instrument that helps BDD, this doesn’t imply you’re practising BDD simply by utilizing Cucumber. The Cucumber myths is an attention-grabbing learn on this regard.
Within the the rest of this weblog, you’ll study extra concerning the options of Cucumber when growing a Java software. Do know, that Cucumber shouldn’t be restricted to testing Java functions, a large record of languages is supported.
The sources used on this weblog might be discovered on GitHub.
Conditions
Conditions for this weblog are:
- Foundation Java information, Java 21 is used;
- Fundamental Maven information;
- Fundamental comprehension of BDD, see the sources within the introduction.
Challenge Setup
An preliminary mission might be setup by the use of the Maven cucumber-archetype
. Change the groupId
, artifactId
and bundle
to suit your preferences and execute the next command:
$ mvn archetype:generate
"-DarchetypeGroupId=io.cucumber"
"-DarchetypeArtifactId=cucumber-archetype"
"-DarchetypeVersion=7.17.0"
"-DgroupId=mycucumberplanet"
"-DartifactId=mycucumberplanet"
"-Dpackage=com.mydeveloperplanet.mycucumberplanet"
"-Dversion=1.0.0-SNAPSHOT"
"-DinteractiveMode=false"
The mandatory dependencies are downloaded and the mission construction is created. The output ends with the next:
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Whole time: 2.226 s
[INFO] Completed at: 2024-04-28T10:25:16+02:00
[INFO] ------------------------------------------------------------------------
Open the mission along with your favourite IDE. In case you are utilizing IntelliJ, a message is proven so as to set up a plugin.
Take a better have a look at the pom:
- The
dependencyManagement
part accommodates BOMs (Invoice of Supplies) for Cucumber and JUnit; - A number of dependencies are added for Cucumber and JUnit;
- The
construct
part accommodates the compiler plugin and the surefire plugin. The compiler is ready to Java 1.8, change it into 21.
io.cucumber
cucumber-bom
7.17.0
pom
import
org.junit
junit-bom
5.10.2
pom
import
io.cucumber
cucumber-java
check
io.cucumber
cucumber-junit-platform-engine
check
org.junit.platform
junit-platform-suite
check
org.junit.jupiter
junit-jupiter
check
org.apache.maven.plugins
maven-compiler-plugin
3.13.0
UTF-8
21
org.apache.maven.plugins
maven-surefire-plugin
3.2.5
Within the check
listing, you will notice a RunCucumberTest
, StepDefinitions
and an instance.function
file within the sources part.
The RunCucumberTest
file is important to run the function recordsdata and the corresponding steps. The function recordsdata and steps will probably be mentioned in a while, don’t worry an excessive amount of about it now.
@Suite
@IncludeEngines("cucumber")
@SelectPackages("com.mydeveloperplanet.mycucumberplanet")
@ConfigurationParameter(key = PLUGIN_PROPERTY_NAME, worth = "pretty")
public class RunCucumberTest {
}
Run the assessments, the output must be profitable.
Write Situation
When practising BDD, you have to to put in writing a situation first. Taken from the Cucumber documentation:
Once we do Conduct-Pushed Growth with Cucumber we use concrete examples to specify what we wish the software program to do. Situations are written earlier than manufacturing code. They begin their life as an executable specification. Because the manufacturing code emerges, eventualities tackle a task as dwelling documentation and automatic assessments.
The appliance it’s worthwhile to construct for this weblog is a fairly fundamental one:
- You want to have the ability to add an worker;
- It’s good to retrieve the whole record of staff;
- You want to have the ability to take away all staff.
A function file follows the Given-When-Then (GWT) notation. A function file consists of:
- A function title. It’s suggested to take care of the identical title because the file title;
- A function description;
- A number of eventualities containing steps within the GWT notation. A situation illustrates how the applying ought to behave.
Characteristic: Worker Actions
Actions to be made for an worker
Situation: Add worker
Given an empty worker record
When an worker is added
Then the worker is added to the worker record
Run the assessments and you’ll discover now that the function file is executed. The assessments fail after all, however an instance code is offered so as to create the step definitions.
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] Operating com.mydeveloperplanet.mycucumberplanet.RunCucumberTest
Situation: Add worker # com/mydeveloperplanet/mycucumberplanet/employee_actions.function:4
Given an empty worker record
When an worker is added
Then the worker is added to the worker record
[ERROR] Exams run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.104 s
Add Step Definitions
Add the instance code from the output above into the StepDefinitions
file. Run the assessments once more. After all, they fail, however this time a PendingException
is thrown indicating that the steps must be applied.
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] Operating com.mydeveloperplanet.mycucumberplanet.RunCucumberTest
Situation: Add worker # com/mydeveloperplanet/mycucumberplanet/employee_actions.function:4
Given an empty worker record # com.mydeveloperplanet.mycucumberplanet.StepDefinitions.an_empty_employee_list()
io.cucumber.java.PendingException: TODO: implement me
at com.mydeveloperplanet.mycucumberplanet.StepDefinitions.an_empty_employee_list(StepDefinitions.java:12)
at ✽.an empty worker record(classpath:com/mydeveloperplanet/mycucumberplanet/employee_actions.function:5)
When an worker is added # com.mydeveloperplanet.mycucumberplanet.StepDefinitions.an_employee_is_added()
Then the worker is added to the worker record # com.mydeveloperplanet.mycucumberplanet.StepDefinitions.the_employee_is_added_to_the_employee_list()
[ERROR] Exams run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.085 s
Implement Utility
The primary situation is outlined, let’s implement the applying. Create a fundamental EmployeeService
which provides the wanted performance. An worker might be added to an worker record which is only a map of staff. The record of staff might be retrieved and the record might be cleared.
public class EmployeeService {
non-public remaining HashMap staff = new HashMap();
non-public Lengthy index = 0L;
public void addEmployee(String firstName, String lastName) {
Worker worker = new Worker(firstName, lastName);
staff.put(index, worker);
index++;
}
public Assortment getEmployees() {
return staff.values();
}
public void removeEmployees() {
staff.clear();
}
}
The worker is a fundamental document.
public document Worker(String firstName, String lastName) {
}
Implement Step Definitions
Now that the service exists, you’ll be able to implement the step definitions. It’s moderately easy, you create the service and invoke the strategies for the Given-When implementations. Verifying the result’s accomplished by Assertions, simply as you’ll do in your unit assessments.
public class StepDefinitions {
non-public remaining EmployeeService service = new EmployeeService();
@Given("an empty employee list")
public void an_empty_employee_list() {
service.removeEmployees();
}
@When("an employee is added")
public void an_employee_is_added() {
service.addEmployee("John", "Doe");
}
@Then("the employee is added to the employee list")
public void the_employee_is_added_to_the_employee_list() {
assertEquals(1, service.getEmployees().measurement());
}
}
Run the assessments, that are profitable now.
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] Operating com.mydeveloperplanet.mycucumberplanet.RunCucumberTest
Situation: Add worker # com/mydeveloperplanet/mycucumberplanet/employee_actions.function:4
Given an empty worker record # com.mydeveloperplanet.mycucumberplanet.StepDefinitions.an_empty_employee_list()
When an worker is added # com.mydeveloperplanet.mycucumberplanet.StepDefinitions.an_employee_is_added()
Then the worker is added to the worker record # com.mydeveloperplanet.mycucumberplanet.StepDefinitions.the_employee_is_added_to_the_employee_list()
[INFO] Exams run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.081 s -- in com.mydeveloperplanet.mycucumberplanet.RunCucumberTest
[INFO]
[INFO] Outcomes:
[INFO]
[INFO] Exams run: 1, Failures: 0, Errors: 0, Skipped: 0
Additional Situation
Add a second situation that assessments the removing of staff. Add the situation to the function file.
Situation: Take away staff
Given a stuffed worker record
When the staff record is eliminated
Then the worker record is empty
Implement the step definitions.
@Given("a filled employee list")
public void a_filled_employee_list() {
service.addEmployee("John", "Doe");
service.addEmployee("Miles", "Davis");
assertEquals(2, service.getEmployees().measurement());
}
@When("the employees list is removed")
public void the_employees_list_is_removed() {
service.removeEmployees();
}
@Then("the employee list is empty")
public void the_employee_list_is_empty() {
assertEquals(0, service.getEmployees().measurement());
}
Tags
In an effort to run a subset of eventualities, you’ll be able to add tags to options and eventualities.
@regression
Characteristic: Worker Actions
Actions to be made for an worker
@TC_01
Situation: Add worker
Given an empty worker record
When an worker is added
Then the worker is added to the worker record
@TC_02
Situation: Take away staff
Given a stuffed worker record
When the staff record is eliminated
Then the worker record is empty
Run solely the check annotated with TC_01 by utilizing a filter.
$ mvn clear check -Dcucumber.filter.tags="@TC_01"
...
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] Operating com.mydeveloperplanet.mycucumberplanet.RunCucumberTest
[WARNING] Exams run: 2, Failures: 0, Errors: 0, Skipped: 1, Time elapsed: 0.233 s -- in com.mydeveloperplanet.mycucumberplanet.RunCucumberTest
[INFO]
[INFO] Outcomes:
[INFO]
[WARNING] Exams run: 2, Failures: 0, Errors: 0, Skipped: 1
Reporting
When executing assessments, it’s usually required that acceptable reporting is obtainable. Up until now, solely console output has been proven.
Generate an HTML report by including the next configuration parameter to the RunCucumberTest.
@Suite
@IncludeEngines("cucumber")
@SelectPackages("com.mydeveloperplanet.mycucumberplanet")
@ConfigurationParameter(key = PLUGIN_PROPERTY_NAME, worth = "pretty")
@ConfigurationParameter(key = PLUGIN_PROPERTY_NAME, worth = "html:target/cucumber-reports.html")
public class RunCucumberTest {
}
After operating the check, a moderately fundamental HTML report is obtainable within the specified path.
A number of third-party reporting plugins can be found. The cucumber-reporting-plugin provides a extra elaborate report. Add the dependency to the pom.
me.jvt.cucumber
reporting-plugin
5.3.0
Allow the report in RunCucumberTest
.
@Suite
@IncludeEngines("cucumber")
@SelectPackages("com.mydeveloperplanet.mycucumberplanet")
@ConfigurationParameter(key = PLUGIN_PROPERTY_NAME, worth = "pretty")
@ConfigurationParameter(key = PLUGIN_PROPERTY_NAME, worth = "html:target/cucumber-reports.html")
@ConfigurationParameter(key = PLUGIN_PROPERTY_NAME, worth = "me.jvt.cucumber.report.PrettyReports:target/cucumber")
public class RunCucumberTest {
}
Run the assessments and within the goal/cucumber
listing the report is generated. Open the file beginning with report-feature
.
Conclusion
Cucumber has nice help for BDD. It’s fairly simple to make use of and on this weblog, you solely scratched the floor of its capabilities. A bonus is that you may make use of JUnit and Assertions and the steps might be applied by the use of Java. No have to study a brand new language when your software can also be inbuilt Java.