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

  • Projections/DTOs in Spring Data R2DBC
  • Testcontainers With Kotlin and Spring Data R2DBC
  • Using Barcodes in iText 7
  • Reliability Models and Metrics for Test Engineering

Trending

  • Getting Started With Microsoft Tool Playwright for Automated Testing
  • Enhance IaC Security With Mend Scans
  • Mastering System Design: A Comprehensive Guide to System Scaling for Millions, Part 2
  • Data Governance: Data Integration (Part 4)
  1. DZone
  2. Data Engineering
  3. Data
  4. How To Use Builder Design Pattern and DataFaker Library for Test Data Generation in Automation Testing

How To Use Builder Design Pattern and DataFaker Library for Test Data Generation in Automation Testing

In this tutorial, learn how to use a builder design pattern in Java with a DataFaker library to generate test data for automation testing.

By 
Faisal Khatri user avatar
Faisal Khatri
·
Jun. 15, 24 · Tutorial
Like (5)
Save
Tweet
Share
11.0K Views

Join the DZone community and get the full member experience.

Join For Free

I bet you might have come across a scenario while automating API/web or mobile applications where, while registering a user, you may be setting the address for checking out a product in the end-to-end user journey in test automation.

So, how do you do that?

Normally, we create a POJO class in Java with the fields required to register a user or to set the address for checking out the product and then set the values in the test using the constructor of the POJO class.

Let’s take a look at an example of registering a user where the following are mandatory fields required to fill in the registration form:

  1. First Name
  2. Last Name
  3. Address
  4. City
  5. State
  6. Country
  7. Mobile Number

As we need to handle these fields in automation testing we will have to pass on respective values in the fields at the time of executing the tests.

Before Using the Builder Pattern

A POJO class, with the above-mentioned mandatory fields, will be created with the Getter and Setter methods inside that POJO class, and using a constructor values are set in the respective fields.

Check out the code example of RegisterUser class given below for the representation of what we are discussing.

Java
 
public class RegisterUser {
    private String firstName;
    private String lastName;
    private String address;
    private String city;
    private String state;
    private String country;
    private String mobileNumber;

    public RegisterUser (final String firstName, final String lastName, final String address, final String city,
        final String state, final String country, final String mobileNumber) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.address = address;
        this.city = city;
        this.state = state;
        this.country = country;
        this.mobileNumber = mobileNumber;
    }

    public String getFirstName () {
        return firstName;
    }

    public void setFirstName (final String firstName) {
        this.firstName = firstName;
    }

    public String getLastName () {
        return lastName;
    }

    public void setLastName (final String lastName) {
        this.lastName = lastName;
    }

    public String getAddress () {
        return address;
    }

    public void setAddress (final String address) {
        this.address = address;
    }

    public String getCity () {
        return city;
    }

    public void setCity (final String city) {
        this.city = city;
    }

    public String getState () {
        return state;
    }

    public void setState (final String state) {
        this.state = state;
    }

    public String getCountry () {
        return country;
    }

    public void setCountry (final String country) {
        this.country = country;
    }

    public String getMobileNumber () {
        return mobileNumber;
    }

    public void setMobileNumber (final String mobileNumber) {
        this.mobileNumber = mobileNumber;
    }
}


Now, if we want to use this POJO, we would have to create an instance of RegisterUser class and pass the values in the constructor parameters as given in the code example below to set the data in the respective fields.

Check out the below example of the Register User test of how we do it.

Java
 
public class RegistrationTest {

    @Test
    public void testRegisterUser () {
        RegisterUser registerUser = new RegisterUser ("John", "Doe", "302, Adam Street, 1st Lane", "New Orleans",
            "New Jersey", "US", "52145364");

        assertEquals (registerUser.getFirstName (), "John");
        assertEquals (registerUser.getCountry (), "US");
    }
}


There were just seven fields in the example we took for registering the user. However, this would not be the case with every application. There would be some more additional fields required and as the fields keep on increasing every time, we would need to update the POJO class with respective Getter and Setter methods and also update the parameters in the constructor.

Finally, we would need to add the values to those fields so the data could be passed in the actual field required.

Long story short, we would need to update the code even if there is a single new field added, also, it doesn’t look clean to add values as parameters in the tests.

Luckily, the Builder Design Pattern in Java comes to the rescue here.

available on GitHub

What Is Builder Design Pattern in Java?

Builder design pattern is a creational design pattern that lets you construct complex objects step by step. The pattern allows you to produce different types and representations of an object using the same construction code. 

Builder Pattern helps us solve the issue of setting the parameters by providing a way to build the objects step by step by providing a method that returns the final object which can be used in the actual tests.

What Is Lombok?

Project Lombok is a Java library that automatically plugs into your editor and builds tools, spicing up your Java. It is an annotation-based Java library that helps in reducing the boilerplate code.

It helps us in writing short and crisp code without having to write the boilerplate code. Bypassing the @Getterannotation over the class, it automatically generates Getter methods. Similarly, you don’t have to write the code for Setter methods as well, its @Setterannotation updated over the class automatically generates the Setter methods.

It also has support for using the Builder design pattern so we just need to put the @Builderannotation above the class and the rest will be taken care of by the Lombok library.

To use Lombok annotations in the project we need to add the following Maven dependency:

<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.32</version>
    <scope>provided</scope>
</dependency>


Using the Builder Design Pattern With Lombok

Before we start refactoring the code we have written, let me tell you about the DataFaker library as well as how it helps in generating fake data that can be used for testing. Ideally, in our example, every newly registered user’s data should be unique otherwise we may get a duplicate data error and the test will fail.

Here, the DataFaker library will help us in providing unique data in each test execution thereby helping us with registering a new user with unique data every time the registration test is run.

To use the DataFaker library, we need to add the following Maven dependency to our project.

XML
 
<!-- https://mvnrepository.com/artifact/net.datafaker/datafaker -->
<dependency>
    <groupId>net.datafaker</groupId>
    <artifactId>datafaker</artifactId>
    <version>2.2.2</version>
</dependency>


Now, let's start refactoring the code. First, we will make the changes to the RegisterUser class. We would be removing all the Getter and Setter methods and also the constructor and adding the @Getter and @Builder annotation tags on the top of the RegisterUser class.

Here is how the RegisterUser class looks now after the refactoring

Java
 
@Getter
@Builder
public class RegisterUserWithBuilder {
    private String firstName;
    private String lastName;
    private String address;
    private String city;
    private String state;
    private String country;
    private String mobileNumber;
}


How clean and crisp it looks with that refactoring being done. Multiple lines of code are removed still it will still work in the same fashion as it used to earlier, thanks to Lombok.

We would have to add a new Java class for generating the fake data on runtime using the Builder design pattern. We would be calling this new class the DataBuilder class.

Java
 
public class DataBuilder {

    private static final Faker FAKER = new Faker();

    public static RegisterUserWithBuilder getUserData () {
        return RegisterUserWithBuilder.builder ()
            .firstName (FAKER.name ()
                .firstName ())
            .lastName (FAKER.name ()
                .lastName ())
            .address (FAKER.address ()
                .streetAddress ())
            .state (FAKER.address ()
                .state ())
            .city (FAKER.address ()
                .city ())
            .country (FAKER.address ()
                .country ())
            .mobileNumber (String.valueOf (FAKER.number ()
                .numberBetween (9990000000L, 9999999999L)))
            .build ();
    }
}


The getUserData() method will return the test data required for registering the user using the DataFaker library. Notice the builder() method used after the class name RegisterUserWithBuilder. It appears because of the @Builder annotation we have used on the top of the RegisterUserWithBuilder class.

After the builder() method we have to pass on the variables we have declared in the RegisterUserWithBuilder class and accordingly, pass the fake data that we need to generate for the respective variables.

Java
 
RegisterUserWithBuilder.builder ()
    .firstName (FAKER.name ()
	.firstName ());


The above piece of code will generate a fake first name and set it in the first name variable. Likewise, we have set fake data in all other variables.

Now, let’s move towards how we use these data in the tests. It's very simple, the below code snippet explains it all. 

Java
 
    @Test
    public void testRegisterUserWithBuilder () {
        RegisterUserWithBuilder registerUserWithBuilder = getUserData ();
      
        System.out.println (registerUserWithBuilder.getFirstName ());
        System.out.println (registerUserWithBuilder.getLastName ());
        System.out.println (registerUserWithBuilder.getAddress ());
        System.out.println (registerUserWithBuilder.getCity ());
        System.out.println (registerUserWithBuilder.getState ());
        System.out.println (registerUserWithBuilder.getCountry ());
        System.out.println (registerUserWithBuilder.getMobileNumber ());
    }


We just need to call the getUserData() method while instantiating the RegisterUserWithBuilder class. Next, we would be calling the Getter methods for the respective variables we declared inside the RegisterUserWithBuilder class. Remember we had passed the @Getter annotation on the top of the RegisterUserWithBuilder class, this actually helps in calling the Getter methods here.

Also, we are not required to pass on multiple data as the constructor parameters for the RegisterUserWithBuilder class, instead we just need to instantiate the class and call the getUserData() method!

How easy it is to generate the unique data and pass it on in the tests without having to write multiple lines of boilerplate codes.

Thanks to the Builder design pattern and Lombok!

Running the Test

Let’s run the test and check if the user details get printed in the console. We can see that the fake data is generated successfully in the following screenshot of the test execution.

running the test

Conclusion

In this blog, we discussed making use of the builder design pattern in Java with Lombok and DataFaker library to generate fake test data on run time and use it in our automated tests. It would ease the test data generation process by eliminating the need to update the test data before running the tests.

I hope it will help you a lot in reducing the code lines and writing your code in a much cleaner way.

Happy Testing!

Builder pattern Data (computing) Java (programming language) Testing

Published at DZone with permission of Faisal Khatri. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Projections/DTOs in Spring Data R2DBC
  • Testcontainers With Kotlin and Spring Data R2DBC
  • Using Barcodes in iText 7
  • Reliability Models and Metrics for Test Engineering

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: