Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Microservices Test Automation: BDD With Cucumber JVM

DZone's Guide to

Microservices Test Automation: BDD With Cucumber JVM

See how you can apply BDD to your microservices tests as we look at using Cucumber to help make testing easier.

· Microservices Zone ·
Free Resource

Learn the Benefits and Principles of Microservices Architecture for the Enterprise

Integration test cases are expected to be executed after deployment on QA environments on microservices.

We can create a separate microservice integration test module to run integration test cases of any microservices and execute on QA deployment. It can be configured with the build pipeline using Jenkins, Bamboo, etc. When the build will be passed after BDD integration is run on QA, then it should be promoted to the staging/pre-prod environment to make sure that all the REST APIs are intact.

Objective

This article will describe current challenges, usage of Cucumber JVM BDD in agile development, setup with Spring Boot, and Jenkins integration. Cucumber has very powerful reporting with graphs and tables, which can be integrated with Jenkins and share the report. It also generates JSON reports, which can be integrated with other applications or integration testing. It simplifies behavioral testing by using a simple English-like language that can be written by business/QA (non-developers) and later converted to a technical integration test case with or without mocking. 

Why BDD?

BDD (Behavior Driven Development) is a methodology for developing software through continuous interaction between developers, QAs, and BAs within the agile team. BDD has these major components:

  • Feature file: It contains feature info like scenarios, steps, and examples (test data). It's written in Gherkin. It's a plain text file with the ".feature" extension.

  • Scenario: Every feature can have multiple positive and negative test scenarios — for example, login with the wrong password, login with the correct login credentials, etc.

  • Step Definitions: Every scenario contains a list of steps.

Given-When-Then

BDD is based on these three major pillars:

1. Given: Precondition.

2. When: Test execution.

3. Then: Acceptance and assertions.

Reference: https://github.com/cucumber/cucumber/wiki/Given-When-Then. Cucumber doesn’t technically distinguish between these three kinds of steps.

Given

The purpose of Givens is to put the system in a known state before the user (or external system) starts interacting with the system (in the When steps). Avoid talking about user interaction in Givens. If you were creating use cases, Givens would be your preconditions.

Examples

  1. Setting up initial data
  2. Setting up the initial configuration
  3. Creating model instances

When

The purpose of When steps are to describe the key action the user performs, such as interacting with a web page. It actually calls the business logic or actual APIs.

Then

The purpose of Then steps is to observe outcomes like JUnit assertions. The observations should be related to the business value/benefit in your feature description. The observations should also be on some kind of output (calculated value, report, user interface, message).

Examples

  • Testing REST APIs or test execution.

  • Verifying that something related to the Given+When is (or is not) in the output.

  • Checking that some external system has received the expected message.

And, But

If you have several Givens, Whens, or Thens, you can write like this:

Scenario: Multiple Givens
    Given one thing
    Given another thing
    Given yet another thing
    When I open my eyes
    Then I see something
    Then I don't see something else


Or you can make it read more fluently by writing

Scenario: Multiple Givens
    Given one thing
      And another thing
      And yet another thing
    When I open my eyes
    Then I see something
      But I don't see something else


  1. Simplicity: No-technical syntax of features files. Features files are written in plain English, which can be linked with Agile stories.
  2. Communication between business and development is extremely focused as a result of a common English-type language.
  3. The code is easier to maintain, flexible, and extendable.
  4. The code is self-documenting with the examples.
  5. Test data can be changed only in the features file, not in the code.
  6. Stories are easier to “groom” – breakdown, task, and plan.
  7. There is more visibility into team progress and status using reports. Cucumber reports can be shared with top level management, integrated with Jenkins and configured with email notifications. It can also be integrated with automated build and deployment tools like Jenkins email plugins.

Unit Testing vs. TDD vs. BDD

Unit testing is for testing individual modules, whereas TDD is based on writing test cases first and then writing code to make that pass. BDD is based on the behavioral testing based on real scenarios (which can't be tested in TDD). Testing microservices REST APIs are a good example.

Reference: This article has detail comparison matrix with other BDD tools: https://codeutopia.net/blog/2015/03/01/unit-testing -tdd-and-bdd/.

Why BDD with Cucumber? Pros/Cons:

Note: Please refer this comparison reference with other BDD tools/APIs: https://dzone.com/articles/brief-comparison-bdd.

Cucumber is a very powerful framework for BDD testing. It has many useful features like testing by example (data tables, which can be part of the test cases ) or parameters, which can be passed directly from feature file(s). Multiple sets of tests can be sent to BDD test cases. Test data can be passed from the feature files without touching code or making changes in properties resource files. Features files and the related code looks readable and maintainable. Additionally, Cucumber supports many different languages and platforms like Ruby, Java, or .NET.

Getting Started With Cucumber

Cucumber setup with SpringBoot, RestAssured, AssertJ, and JSONAssert.

This sample code/POC is developed using Cucumber with SpringBoot v1.5.1, RestAssured v3.0.3, AssertJ and Java 8.

Cucumber Maven Dependencies:

<dependencies>
  <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifac
tId>
  </dependency>
  <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifa
ctId>
  </dependency>
   <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
   <optional>true</optional>
  </dependency>
  <dependency>
   <groupId>info.cukes</groupId>
   <artifactId>cucumber-spring</artifactId>
   <version>${cucumber.version}</version>
  </dependency>
  <dependency>
   <groupId>io.rest-assured</groupId>
   <artifactId>rest-assured</artifactId>
   <version>${restassured.version}</version>
  </dependency>
  <dependency>
   <groupId>info.cukes</groupId>
   <artifactId>cucumber-junit</artifactId>
   <version>${cucumber.version}</version>
   <scope>test</scope>
  </dependency>
  <dependency>
   <groupId>info.cukes</groupId>
   <artifactId>cucumber-java</artifactId>
   <version>${cucumber.version}</version>
   <scope>test</scope>
  </dependency>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-tx</artifactId>
  </dependency>
  <dependency>
<groupId>com.googlecode.json-simple</groupId>
   <artifactId>json-simple</artifactId>
  </dependency>
  <dependency>
   <groupId>com.jayway.jsonpath</groupId>
   <artifactId>json-path-assert</artifactId>
   <scope>test</scope>
   </dependency>
</dependencies>


Feature file:

@signupServices
     Feature: Cucumber -  SignUp Services
     Integration Test
     Scenario Outline: set initial configuration
     for SignUp Services
      Given app API Key header "<api_key>"
      And user id is "<userId>"
      And user password is "<password>"
      When access token service is called
      Then retrun access token
      And response code is 200
      Examples:
       |api_key | userId |
     password | client_id|
       | test************ | password |
     rajivtest5@test.com | test************* | test*********** |

Advanced Reporting Dashboard

Image title

Run Cucumber Test Cases From the Command Line

To run Cucumber from the command line, you need to add this Maven plug-in.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
        <testFailureIgnore>true</testFailureIgnore>
        <includes>
            <exclude>**/*CucumberRunner.java</exclude>
        </includes>
    </configuration>
</plugin>

Now, Cucumber integration tests can be run by simply using:

# Run integration test cases
$ mvn verify

Test Suite Using Cucumber

Cucumber has a feature to group features/scenarios as a group, which is called a "tag". It can be annotated in the feature file by using @, for example, @signupServices. These test suites can be run individually based on your requirements.

# Run a Cucumber test suite
$ mvn clean test -Dcucumber.options="--tags @encryptionServices"
-Dspring.profiles.active=dev
# Run multiple Cucumber test suites
$ mvn clean test -Dcucumber.options="--tags
@signupServices,@loyaltyService" -Dspring.profiles.active=dev
# Run a Cucumber test suites and also generate detail report with
graphs and jar/class files
$ mvn clean install -Dcucumber.options="--tags @loyaltyService"
-Dspring.profiles.active=dev
#Run all test suites and also generate detail report with graphs
and jar/class files
$ mvn clean install


Cucumber Jenkin Integration

Please refer these links to configure with Jenkin.

Note: The same Maven test plugins seen above will be required to create multiple Jenkins profiles for each feature or group of features by adding tags.

Microservices for the Enterprise eBook: Get Your Copy Here

Topics:
bdd ,cucumber ,automation testing ,testing ,microservices ,tutorial

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}