DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • API Testing With Cucumber
  • 6 of the Best API Testing Tools in the Market
  • Top 10 Best Tips for API Testing (API Testing Tips)
  • Day in the Life of a Developer With Google’s Gemini Code Assist: Part 1

Trending

  • Kubeflow: Driving Scalable and Intelligent Machine Learning Systems
  • AI-Based Threat Detection in Cloud Security
  • Revolutionizing Financial Monitoring: Building a Team Dashboard With OpenObserve
  • Docker Model Runner: Streamlining AI Deployment for Developers
  1. DZone
  2. Software Design and Architecture
  3. Integration
  4. API Testing With Cucumber BDD - Configuration Tips

API Testing With Cucumber BDD - Configuration Tips

In this post we take a look at how to configure Cucumber BDD to help test Spring Boot APIs. The tips in this post will make your life easier!

By 
Grigor Avagyan user avatar
Grigor Avagyan
·
Aug. 28, 17 · Tutorial
Likes (7)
Comment
Save
Tweet
Share
23.8K Views

Join the DZone community and get the full member experience.

Join For Free

BDD (Behavior-Driven Development) is a way of developing code based on the expected behavior of the code as experienced by the users. When testing APIs for BDD tests, it’s important to configure BDD correctly and to keep the count of BDDs to a minimum. This blog post will show best practices to configuring the execution of BDD tests through open-source Cucumber, to execute Spring Boot APIs. To run the tests yourselves, you can find the source code here - blazedemo.

BDD is a type of software development process where the specification and design of an application are determined according to what its behavior should look like to users. BDD is also known as acceptance tests. There are two sides of the coin when it comes to BDD: on the one hand, it enables non-techie people in the company to contribute directly to test automation. This can be done even in the project’s source code, by giving them a place where they can directly write their criteria. On the other hand, it is very difficult to maintain and support.

BDD Configuration for API Execution

1. Create a new empty Java project on IntelliJ IDEA. For more details on how to do that, take a look here (step 1).

Image title

2. Now that we have a project, we need to setup the dependencies. You can use these dependencies, since they are public.

To do that, double click on your build.gradle file and add the following Gradle configuration file:

group 'blazemeter'
version '1.0-SNAPSHOT'

buildscript {
   repositories {
       jcenter()
       mavenCentral()
       maven { url "http://repo.spring.io/libs-snapshot" }
   }
   dependencies {
       classpath("org.springframework.boot:spring-boot-gradle-plugin:1.5.2.RELEASE")
   }
}

apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'org.springframework.boot'

sourceSets {
   main.java.srcDir "src/main/java"
   main.resources.srcDir "src/main/resources"
   test.java.srcDir "src/test/java"
   test.resources.srcDir "src/test/resources"
}

jar {
   baseName = 'blaze-demo-api'
   version =  '1.0'
}

bootRepackage {
   mainClass = 'com.demo.BlazeMeterApi'
}

dependencyManagement {
   imports {
       mavenBom 'io.spring.platform:platform-bom:Brussels-SR2'
   }
}

repositories {
   mavenCentral()
   jcenter()
   maven { url "http://repo.spring.io/libs-snapshot" }
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

dependencies {

   compile group: 'org.springframework', name: 'spring-core'
   compile group: 'org.springframework.boot', name: 'spring-boot-starter-jdbc'
   compile group: 'org.springframework.boot', name: 'spring-boot-starter-web'
   compile group: 'org.springframework.boot', name: 'spring-boot-starter-actuator'
   compile group: 'org.springframework.boot', name: 'spring-boot-starter-security'
   compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa'
   compile group: 'org.springframework.security.oauth', name: 'spring-security-oauth2'
   compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-hibernate4'
   compile group: 'mysql', name: 'mysql-connector-java'
   compile group: 'io.rest-assured', name: 'rest-assured', version: '3.0.3'
   compile group: 'io.rest-assured', name: 'json-schema-validator', version: '3.0.3'

   compile group: 'info.cukes', name: 'cucumber-spring', version: '1.2.5'
   compile group: 'info.cukes', name: 'cucumber-junit', version: '1.2.5'

   testCompile group: 'org.springframework.boot', name: 'spring-boot-starter-test'
   testCompile group: 'org.springframework.security', name: 'spring-security-test'
   testCompile group: 'junit', name: 'junit'
   testCompile group: 'org.hsqldb', name: 'hsqldb'
}

In this script, there are only two dependencies for Cucumber itself:

compile group: 'info.cukes', name: 'cucumber-spring', version: '1.2.5'
compile group: 'info.cukes', name: 'cucumber-junit', version: '1.2.5'

All the rest are libs/dependencies for the API project itself (including unit and REST assure testing).

3. Install a Cucumber plugin. The plugin can be installed directly from IntelliJ by going to Preferences -> Plugins -> Install JetBrains plugin.

The Cucumber plugin will create/generate/auto-create the JAVA CODE. This plugin gives us two main benefits: code completion in a feature file as well as implementing methods of the feature steps directly from the feature file.

The features file is the place for non-techies to write criteria/tests. Keep is as small as possible, with meaningful input only, and include all the steps in it. This is important for making technical maintenance and support as efficient as possible.

Here is an example of a short features file:

Feature: API BDDs

 @FirstScenario
 Scenario: Receive single arrival
   Given Arrival rest endpoint is up
   When User gets one arrival by id 1
   Then Returned JSON object is not null

 Scenario: Receive single departure
   Given Departure rest endpoint is up
   When User gets one departure by id 1
   Then Returned JSON object is not null

 Scenario: Receive single flight
   Given Flight rest endpoint is up
   When User gets one flight by id 1
   Then Returned JSON object is not null
 
 @LastScenario
 Scenario: Receive single user
   Given Users rest endpoint is up
   When User gets one user by id 1
   Then Returned JSON object is not null

4. By clicking Alt + Enter on the line of feature step, we will get the following popup window:

Image title

In the popup you can select “Create step definition” that will create a step definition only for the selected row from the feature file, or “Create all steps definition” that will generate methods for all the steps in the Java classes.

For example, if we select “Create step definition”, we will see the step definition class creation popup, which will create the Java class as an output with a defined name and a defined path.

Image title

As usual, you can store your test files anywhere in the src/test/java, according to your personal preferences. I will group them according to test types: unit, rest, bdd, etc.

Don’t forget to name the class for step definitions. Obviously you can do this manually without any Intellij IDEA generation.

Tip #2 - Group All Step Definitions in One Place

To ensure smooth running and code readability, it’s important to put all your step definition files in one place. This will enable Cucumber to find the steps and feature files easily. As you can see from the screenshot below, we create a folder named “bdd” and a subfolder named “steps” and put all the testing steps in it.

Image title

Then, we added a file holder for BDD Cucumber (named “BddCoverage” in this example). The BddCoverage.java class is important because it groups the steps, so Cucumber knows the name of our test suite and where to collect steps and feature files from. This is part of the @CucumberOptions annotation, and done via Glue:

package com.demo.bdd;

import cucumber.api.CucumberOptions;
import cucumber.api.junit.Cucumber;
import org.junit.runner.RunWith;
import org.springframework.test.context.ActiveProfiles;

@RunWith(Cucumber.class)
@CucumberOptions(
       glue = {"com.demo.bdd.steps"},
       features = {"classpath:bdd/features"}
)
@ActiveProfiles(value = "test")
public class BddCoverage {
}

5. You will receive an auto-generated file from the plugin, which shows the class code with all the steps. Add your code to it, instead of the sample code that will appear in it. Below you can see the part that shows the ArrivalsSteps class.

package com.demo.bdd.steps;

import com.demo.bdd.BlazeMeterFeatureTest;
import cucumber.api.java.en.When;
import org.slf4j.Logger;

import static org.slf4j.LoggerFactory.getLogger;

public class ArrivalsSteps extends BlazeMeterFeatureTest {

   private static final Logger LOGGER = getLogger(ArrivalsSteps.class);

   @When("^User gets one arrival by id (\\d+)$")
   public void userGetsOneArrivalById(int id) throws Throwable {
       LOGGER.info("When - User gets one arrival by id [{}]", id);
   }
}

You can also create your own file. This is the CommonSteps file, which I manually created:

package com.demo.bdd.steps;
import com.demo.bdd.BlazeMeterFeatureTest;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import org.slf4j.Logger;
import static org.slf4j.LoggerFactory.getLogger;

public class CommonSteps extends BlazeMeterFeatureTest {

   private static final Logger LOGGER = getLogger(CommonSteps.class);

   @Given("^(.+) rest endpoint is up$")
   public void arrivalRestEndpointIsUp(String endpointType) throws Throwable {
       LOGGER.info("Given - [{}] rest endpoint is up", endpointType);
   }

   @Then("^Returned JSON object is not null$")
   public void returnedJSONObjectIsNotNull() {
       LOGGER.info("Then - Returned JSON object is not null");
   }
}

To ensure your application runs properly, create an Abstract Class. The Abstract Class ensures the API runs automatically before the tests, and not separately. In this example, we named the class “BlazeMeterFeatureTest.”

Image title

The Abstract class that will help us run SpringContext and a random port. As result, all our step classes will extend this one.

package com.demo.bdd;

import com.demo.BlazeMeterApi;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ContextConfiguration;

@ContextConfiguration
@SpringBootTest(
       classes = BlazeMeterApi.class,
       webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT
)
public abstract class BlazeMeterFeatureTest {
}

6, Now let’s run the the tests! Right click on “bdd” and select Run ’Tests in ‘bdd’’ as shown in the picture below:

Image title

Here are the results of the execution. On the left pane you can see the scenario execution results, and on the right pane you can see the log output and the amount of tests that were run and that passed:

Image title

That’s it! You now know how to run Unit Tests with JUnit for REST APIs.

API Cucumber (software) unit test intellij API testing

Published at DZone with permission of , DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • API Testing With Cucumber
  • 6 of the Best API Testing Tools in the Market
  • Top 10 Best Tips for API Testing (API Testing Tips)
  • Day in the Life of a Developer With Google’s Gemini Code Assist: Part 1

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!