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
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

Low-Code Development: Leverage low and no code to streamline your workflow so that you can focus on higher priorities.

DZone Security Research: Tell us your top security strategies in 2024, influence our research, and enter for a chance to win $!

Launch your software development career: Dive head first into the SDLC and learn how to build high-quality software and teams.

Open Source Migration Practices and Patterns: Explore key traits of migrating open-source software and its impact on software development.

Related

  • Integrate Cucumber in Playwright With Java
  • Keep Your Application Secrets Secret
  • What Java Developers Need to Know About Geo-Distributed Databases
  • Simplify Java Persistence Using Quarkus and Hibernate Reactive

Trending

  • Performance and Scalability Analysis of Redis and Memcached
  • PostgreSQL BiDirectional Replication
  • Difference Between App Development and IaC CI/CD Pipelines
  • Explainable AI: Seven Tools and Techniques for Model Interpretability
  1. DZone
  2. Culture and Methodologies
  3. Agile
  4. What BDD Is and Why You Need It: Java and Behavior Driven Development

What BDD Is and Why You Need It: Java and Behavior Driven Development

This article explains what BDD is and how Behavior Driven Development helps the developer and their team to understand application logic.

By 
Dmitry Egorov user avatar
Dmitry Egorov
DZone Core CORE ·
Nov. 19, 21 · Tutorial
Like (8)
Save
Tweet
Share
10.9K Views

Join the DZone community and get the full member experience.

Join For Free

Is Behavior Driven Development Just Another Religion?

You might hear about BDD but still don't have a clear understanding of what it is. Here I'll try to simplify the main ideas and provide clear examples. This article is useful not only for developers but all people involved in the development process like analysts, product owners, and even guys from the business.

BDD Makes Application Logic More Transparent

Low Transparency in Application is a very known problem in IT. Quite often domain knowledge belongs only to the development team. As a consequence, to get even a simple answer you have to ask the developer to explain.

Application cartoon.

Behavior Driven Development is a set of practices that makes application logic more transparent not only for developers but also for business guys, product owners, designers, etc.  BDD it's not magic and won't make applications perfectly transparent for everyone: developers still have a knowledge advantage. But, this practice is very useful. Funny thing is that in practice this BDD approach helps developers the most.

Writing Simple Application as Case Study

To show how BDD can improve application transparency let's implement a simple user creation service. The design of such a service will be pretty straightforward - create/read/delete users.  

Java
 
public class UserService {
    private final Map<String, User> users;
   
    public UserService(){
        users = new HashMap<>();
    }

    public User createUser(User user){
        if(users.get(user.getName()) != null) throw new RuntimeException("User Exist!");
        users.put(user.getName(), user);
        return user;
    }

    public User getUser(String user){
        return users.get(user);
    }

}
@Data
class User{
  private String name;
  private String password;
  private String info;
}


Implementing Tests in Old Fashion Style (No BDD Here)

For beginning let's write a couple of tests following the classical approach. Some Junit asserts for positive and negative cases.

Java
 
@Test
public void userCreatedSuccessfully() {
  User actual = userService.createUser(new User("John", "Smith"));
  assertEquals(actual, userService.getUser("John"));
}

@Test(expected = RuntimeException.class)
public void existentUserError() {
  userService.createUser(new User("John", "Smith"));
  userService.createUser(new User("John", "Dorian"));
}

@Test(expected = RuntimeException.class)
public void tooShortName() {
  userService.createUser(new User("ab", "Smith"));
}


For the average Java developer, you won't find anything complex. But, all other participants in the team might react like this:

Jim Carey GIF.

Product owner desperately trying to understand tests.

Introducing BDD Practice by Adding Cucumber Tests

Now let's introduce BDD and rewrite our regular tests by Cucumber tests. The cucumber framework provides BDD support for many languages and hopefully, Java is among them. One of the fundamental things is scenarios that describe scenarios of the tests. The main purpose of such scenarios - make tests easier to read and to understand. Scenarios are described inside *.feature files.

Explaining Feature Files

Feature file has a couple of keywords provided by Cucumber like Given/When/Then. Actually, you can use them in the way you want and the framework doesn't have any restrictions. All of them are used only for one purpose - to create similar natural language scenarios. Such scenarios will be much more clear for non-developers like designers/analysts/product owners. So, let's take a look at our feature file (there is a link to source code at the end of the article):

Feature file image.So, in our file, we can see 4 scenarios. Examples are pretty straightforward and don't show all features given by Cucumber. But basic functionality is shown. Data from the feature file is after passing the Java test. Here you can see how it looks like:

Java
 
private UserService userService;

@Given("^User API is initiated$")
public void initializeUserService() {
  userService = new UserService();
}

@When("^Creating user (\\w+) with age (\\d+) calling user API$")
public void createUser(String name, int age) {
  userService.createUser(new User(name, age));
}

@Then("^User Api returns (\\w+) user with (\\d+) age$")
public void validateUserByName(String name, int age) {
  User userFromApi = userService.getUser(name);
  Assert.assertEquals(name, userFromApi.getName());
  Assert.assertEquals(age, userFromApi.getAge());
}

@Then("^Fail to create user (\\w+) with age (\\d+) when calling user API$")
public void failUserCreation(String name, int age) {
  assertThrows(RuntimeException.class, () -> userService.createUser(new User(name, age)), "Should fail");
}

@When("^Creating multiple users$")
public void creatingMultipleUsers(List<User> users) {
  users.forEach(user -> assertNotNull(userService.createUser(user)));
}

@Then("^All created users now available from user API$")
public void createUser(List<User> users) {
  users.forEach(user -> containsInAnyOrder(users, userService.getUser(user.getName())));
}


It might look overcomplicated but actually, there is nothing complex. For each word used in Given/Then/When Cucumber finds a corresponding function in the test. Also, cucumber automatically deserializes data from feature records to method parameters.

One of the options is to write regex like statements:

Another way to write a column like records that mapped to arrays:

Another example of writing a column.

The source code used in this article can be cloned from here or just type: 

git clone https://github.com/isicju/bdd_cucumber_tutorial.git


Advantages of the BDD Approach:

Now having an example we can say that the BDD approach makes:

  • The test becomes more visual and descriptive.
  • All non-developers participants are closer to application functionality.

Well, also it is worth mentioning that tools provided by Cucumber also simplify the process of test writing and maintainability (especially for tests with a big number of inputs e.g. records in databases).  

Is Cucumber a Mandatory Part of BDD?

No. Cucumber provides a set of tools that follow BDD ideas. Potentially you can create your own solution and use frameworks like Spock or even Mockito for the same purpose. But, Cucumber has already become a standard in enterprise development. 

Instead of a Conclusion

I strongly recommend developers add such frameworks when you write your tests. In the very end, such an approach helps developers the most. It's pretty rare when anyone else reads tests and uses them as alternatives to documentation. I expect in the future this approach will be transformed into something better.

Behavior-driven development Java (programming language) Testing Cucumber (software) application dev

Opinions expressed by DZone contributors are their own.

Related

  • Integrate Cucumber in Playwright With Java
  • Keep Your Application Secrets Secret
  • What Java Developers Need to Know About Geo-Distributed Databases
  • Simplify Java Persistence Using Quarkus and Hibernate Reactive

Partner Resources


Comments

ABOUT US

  • About DZone
  • Send 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: