Data Driven

Separate test logic from test data using multiple formats.

Neodymium provides convenient test data handling, with support for the following file formats, prioritized in this order:

  1. CSV
  2. JSON
  3. XML
  4. Properties

Neodymium automatically links test data files found in the resource folder with matching paths to the test, making them accessible. For custom locations, use the @DataFile("<path/to/file>") annotation, ensuring you provide the complete path from the resource folder, including the file extension.

Accessing Data

Neodymium offers various methods for accessing test data. The simplest approach is using Neodymium.getData().asString("<key>"). Other primitive data types can be retrieved in the same way.

The test below illustrates searching for a product using a data-driven search term.

import com.codeborne.selenide.Selenide;
import com.xceptance.neodymium.common.browser.Browser;
import com.xceptance.neodymium.junit5.NeodymiumTest;
import com.xceptance.neodymium.util.Neodymium;
import org.example.pageobjects.pages.HomePage;
import org.example.pageobjects.pages.ProductDetailPage;
import org.example.pageobjects.pages.ProductListingPage;

@Browser
public class TestDataTest
{
    @NeodymiumTest
    public void testDataTest()
    {
        // get the search term from the test data
        String searchTerm = Neodymium.getData().asString("searchTerm");

        // open the test website
        Selenide.open("https://posters.xceptance.io:8443/");

        HomePage homePage = new HomePage().assertExpectedPage();

        // check that the search is available and search for the search term
        homePage.header.assertComponentAvailable();
        ProductListingPage productListingPage = homePage.header.searchForSearchTerm(searchTerm);

        // open the first product and validate the name
        ProductDetailPage productDetailPage = productListingPage.openProductAtPosition(1);
        productDetailPage.validateProductName(searchTerm);
    }
}

A simple JSON file is used to store the test data:

[
  {
    "searchTerm": "bear"
  }
]

Data Objects (POJOs)

Instead of direct data access, you can define a Plain Old Java Object (POJO) to represent your test data. By annotating a POJO attribute in your test class with @DataItem, the test data will be automatically parsed into the object. This method is ideal for complex data structures, as it groups related data into easily accessible objects. Furthermore, you can use multiple data objects within a single test.

We will now expand the TestDataTest to include test data objects.

@Browser
public class TestDataTest
{
    @DataItem
    private SearchData searchData;

    @DataItem
    private Product product;

    @NeodymiumTest
    public void testDataTest()
    {
        // open the test website
        Selenide.open("https://posters.xceptance.io:8443/");

        HomePage homePage = new HomePage().assertExpectedPage();

        // check that the search is available and search for the search term
        homePage.header.assertComponentAvailable();
        ProductListingPage productListingPage = homePage.header.searchForSearchTerm(searchData.getSearchTerm());

        // validate search result count
        productListingPage.validateSearchResultCount(searchData.getExpectedResultCount());

        // open the first product and validate the name
        ProductDetailPage productDetailPage = productListingPage.openProductAtPosition(1);
        productDetailPage.validateProductName(product.getName());
        productDetailPage.validateProduct(product);
    }
}

Using test data objects simplifies the handling of complex JSON test data. Therefore, the JSON for this test has also been extended:

[
  {
    "searchData": {
      "searchTerm": "bear",
      "expectedResultCount": 3
    },
    "product": {
      "name": "Grizzly Bear",
      "price": "$17.00",
      "shortDescription": "Bear looking tired."
    }
  }
]

To map complex JSON data to Java objects, we need to create POJOs. The SearchData class is shown as an example; the Product class follows a similar structure.

public class SearchData
{
    private String searchTerm;

    private Integer expectedResultCount;

    public String getSearchTerm()
    {
        return searchTerm;
    }

    public Integer getExpectedResultCount()
    {
        return expectedResultCount;
    }

    @Override
    public String toString()
    {
        return "SearchData [searchTerm=" + searchTerm + ", expectedResultCount=" + expectedResultCount + "]";
    }
}

Multiple Data Sets

Neodymium automatically runs tests for each data set defined in your data file. This can be controlled by using @SuppressDataSets and @DataSet(). More information can be found in the Test Data chapter.

Let’s add another data set to the test data file:

[
  {
    ...
  },
  {
    "searchData": {
      "searchTerm": "Swiss Air Airbus A320",
      "expectedResultCount": 1
    },
    "product": {
      "name": "Swiss Air Airbus A320",
      "price": "$12.99",
      "shortDescription": "Beautiful take-off."
    }
  }
]

After executing the test with both data sets, we get the following report:

Report of the data driven test TestDataTest with two data sets.

For each data set, the report creates a distinct test method entry within the test class. Each entry includes the data set number in its title and displays the corresponding test data below the steps.

Package Test Data

Package test data allows for sharing common data among tests within the same package and its sub-packages. This data is defined in a file named package_testdata using one of the supported file formats. Utilizing package test data does not result in multiple test method executions (it acts as a common pool of data).

Last modified December 16, 2025: fix image links (4abbede9)