Efficient Java Software Testing With Cucumber and BDD – DZone – Uplaza

Enhance your testing effectivity by using Cucumber for Java software testing, totally built-in with Habits-Pushed Improvement (BDD). This information gives complete steps for challenge setup, situation writing, step implementation, and reporting.

Introduction

Cucumber is a instrument that helps Habits-Pushed Improvement (BDD). start line with the intention to study extra about BDD and Cucumber, are the Cucumber guides. BDD itself was launched by Dan North in 2006, you possibly can learn his weblog introducing BDD. Cucumber, nevertheless, is a instrument that helps BDD, this doesn’t imply you’re training BDD simply through the use of Cucumber. The Cucumber myths is an fascinating learn on this regard.

Within the the rest of this weblog, you’ll study extra concerning the options of Cucumber when creating a Java software. Do know, that Cucumber is just not restricted to testing Java purposes, a large record of languages is supported.

The sources used on this weblog could be discovered on GitHub.

Stipulations

Stipulations for this weblog are:

  • Foundation Java information, Java 21 is used;
  • Fundamental Maven information;
  • Fundamental comprehension of BDD, see the assets within the introduction.

Undertaking Setup

An preliminary challenge could be setup via the Maven cucumber-archetype. Change the groupId, artifactId and package deal 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 challenge construction is created. The output ends with the next:

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Complete time:  2.226 s
[INFO] Completed at: 2024-04-28T10:25:16+02:00
[INFO] ------------------------------------------------------------------------

Open the challenge along with your favourite IDE. In case you are utilizing IntelliJ, a message is proven with the intention to set up a plugin.

Take a better take a look at the pom:

  • The dependencyManagement part comprises BOMs (Invoice of Supplies) for Cucumber and JUnit;
  • A number of dependencies are added for Cucumber and JUnit;
  • The construct part comprises 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
        take a look at
    
 
    
        io.cucumber
        cucumber-junit-platform-engine
        take a look at
    
 
    
        org.junit.platform
        junit-platform-suite
        take a look at
    
 
    
        org.junit.jupiter
        junit-jupiter
        take a look at
    

 

    
        
            org.apache.maven.plugins
            maven-compiler-plugin
            3.13.0
            
                UTF-8
                21
                21
            
        
        
            org.apache.maven.plugins
            maven-surefire-plugin
            3.2.5
        
    

Within the take a look at listing, you will note a RunCucumberTest, StepDefinitions and an instance.characteristic file within the assets part.

The RunCucumberTest file is important to run the characteristic recordsdata and the corresponding steps. The characteristic recordsdata and steps will likely be mentioned afterward, 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 checks, the output ought to be profitable.

Write Situation

When training BDD, you will want to jot down a situation first. Taken from the Cucumber documentation:

After we do Habits-Pushed Improvement with Cucumber we use concrete examples to specify what we would like 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 checks.

The appliance it is advisable to construct for this weblog is a fairly fundamental one:

  • You want to have the ability to add an worker;
  • You’ll want to retrieve the whole record of staff;
  • You want to have the ability to take away all staff.

A characteristic file follows the Given-When-Then (GWT) notation. A characteristic file consists of:

  • A characteristic title. It’s suggested to take care of the identical title because the file title;
  • A characteristic 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 checks and you’ll discover now that the characteristic file is executed. The checks fail after all, however an instance code is offered with the intention to create the step definitions.

[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Working com.mydeveloperplanet.mycucumberplanet.RunCucumberTest
 
Situation: Add worker                            # com/mydeveloperplanet/mycucumberplanet/employee_actions.characteristic:4
  Given an empty worker record
  When an worker is added
  Then the worker is added to the worker record
[ERROR] Checks 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 checks once more. In fact, they fail, however this time a PendingException is thrown indicating that the steps should be applied.

[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Working com.mydeveloperplanet.mycucumberplanet.RunCucumberTest
 
Situation: Add worker                            # com/mydeveloperplanet/mycucumberplanet/employee_actions.characteristic: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.characteristic: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] Checks run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.085 s 

Implement Software

The primary situation is outlined, let’s implement the applying. Create a fundamental EmployeeService which provides the wanted performance. An worker could be added to an worker record which is only a map of staff. The record of staff could be retrieved and the record could be cleared.

public class EmployeeService {
 
    non-public closing 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 report.

public report Worker(String firstName, String lastName) {
}

Implement Step Definitions

Now that the service exists, you possibly can implement the step definitions. It’s reasonably simple, you create the service and invoke the strategies for the Given-When implementations. Verifying the result’s performed by Assertions, simply as you’d do in your unit checks.

public class StepDefinitions {
 
    non-public closing 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().dimension());
    }
 
}

Run the checks, that are profitable now.

[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Working com.mydeveloperplanet.mycucumberplanet.RunCucumberTest
 
Situation: Add worker                            # com/mydeveloperplanet/mycucumberplanet/employee_actions.characteristic: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] Checks run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.081 s -- in com.mydeveloperplanet.mycucumberplanet.RunCucumberTest
[INFO] 
[INFO] Outcomes:
[INFO] 
[INFO] Checks run: 1, Failures: 0, Errors: 0, Skipped: 0

Additional Situation

Add a second situation that checks the removing of staff. Add the situation to the characteristic file.

Situation: Take away staff
    Given a crammed worker record
    When the workers 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().dimension());
}
@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().dimension());
}

Tags

With the intention to run a subset of eventualities, you possibly can 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 crammed worker record
    When the workers record is eliminated
    Then the worker record is empty

Run solely the take a look at annotated with TC_01 through the use of a filter.

$ mvn clear take a look at -Dcucumber.filter.tags="@TC_01"
...
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Working com.mydeveloperplanet.mycucumberplanet.RunCucumberTest
[WARNING] Checks run: 2, Failures: 0, Errors: 0, Skipped: 1, Time elapsed: 0.233 s -- in com.mydeveloperplanet.mycucumberplanet.RunCucumberTest
[INFO] 
[INFO] Outcomes:
[INFO] 
[WARNING] Checks run: 2, Failures: 0, Errors: 0, Skipped: 1

Reporting

When executing checks, it’s usually required that applicable reporting is offered. 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 take a look at, a reasonably fundamental HTML report is offered within the specified path.

A number of third-party reporting plugins can be found. The cucumber-reporting-plugin presents 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 checks 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 straightforward to make use of and on this weblog, you solely scratched the floor of its capabilities. A bonus is which you could make use of JUnit and Assertions and the steps could be applied via Java. No have to study a brand new language when your software can be inbuilt Java.

Share This Article
Leave a comment

Leave a Reply

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

Exit mobile version