How to use the Data Provider pattern in the project.

Photo by Norbert Levajsics on Unsplash

In my recent article, I reviewed the main automation patterns that can be applied in your work if necessary. Today I continue a series of articles devoted to the consideration of design patterns. In this article, we’ll talk about Data Patterns and the data provider pattern.

Data Patterns the main goal is to split data and test logic as well as to reduce boilerplate and code duplication in our tests. It should make them more understandable and easier in maintenance for anyone who works with them.

Data Provider.

Data Provider is one of the most widely used data patterns among test engineers. If you want to implement Data-Driven tests and are willing to run the same test logic on multiple sets of data, you could load the data from outer sources (like Excel or CVS table), remote services, or hardcode them in-place. Also, It allows you to write data-driven tests, which means you can run the same test methods multiple times with different data sets.

A very important function of the TestNG framework is DataProvider.

To use the DataProvider function in your tests, you must declare a method with the @DataProvider annotation and then use this method in the test method using the “dataProvider” attribute in the Test annotation.

To be able to read data from third-party sources, you can use:

This could be done in the way I showed above by reading from the source and returning untyped data (simple array of arrays or strings). But the modern approach would be to utilize the Value Object pattern, we were talking about previously, and provide data in terms of entities.

For more advanced use of Data Provider in TestNG there is an excellent library Test Data Supplier:

Test Data Supplier.

This repository contains TestNG DataProvider wrapper (the latest version is based on TestNG 7.0.0) which helps to supply test data in a more flexible way.

Common DataProvider forces using a quite old and ugly syntax which expects one of the following types to be returned from DP method’s body:

Object[][]
Iterator<Object[]>

That’s weird, as developers tend to use Stream and Collection API for data manipulation in the modern Java world.

Just imaging if you could use the following syntax to supply some filtered and sorted data into the test method’s signature:

If you work with the JUnit framework you can use parameterization.

The @RunWith and @Parameter annotations are used to pass parameter values to the test. @Parameters returns List[]. These values are passed to the constructor as an argument.

Unfortunately, there are quite a few restrictions in JUnit:

  • We must follow the JUnit signature to declare the parameter;
  • The parameter is passed to the class constructor to initialize the class field that will contain the parameter value;
  • The return type of the method with the @Parameters annotation must be List []
  • Data must be of a primitive type (String, int)

But there is an alternative. If you are used to the TestNG syntax and would like to use it in a project with JUnit you can use:

JUnit-dataprovider. A TestNG like dataprovider (see here) runner for JUnit having a simplified syntax compared to all the existing JUnit4 features.

I love using Data Patterns in my automation, they help me to keep my code healthy and handle resources in the most optimized way possible.

I’m a software engineer who specializes in testing and automation. My top languages are Java and Swift. My blog is https://test-engineer.site/

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store