NashTech Blog

Enhancing Gatling Scripts with Dynamic Data and Custom Feeder Strategies

Table of Contents
Feeders in Gatling

Exploring Feeders in Gatling

What is Feeder in Gatling?

Feeders in Gatling act as data providers, injecting inputs into scripts during test execution. These inputs can include user credentials or dynamic transaction details, essential for creating simulations that replicate real-world user interactions. Feeder Strategies enhance the accuracy and comprehensiveness of load tests and support multiple formats, such as CSV, JSON, and in-memory arrays, offering flexibility in data preparation.

Built-in Feeder Strategies

The tool has many ready-made ways to control how information enters your test scripts, which makes testing both adaptable and fast.

  • Circular Feeders: Reuse data in a loop, ideal for repetitive test cases.
  • Queue Feeders: Consume each data item only once, ensuring unique inputs.
  • Random Feeders: Choose values without a pattern to add surprise elements to your tests.
  • Shuffle Feeders: Randomize the order of data for varied test sequences.
  • Batch Feeders: Move information in bundles to use less computer memory.
  • Single Record Feeders: Provide the same record for all virtual users, useful for debugging.
  • Circular with Overflow Feeders: Restart data usage when the end is reached, ideal for exceeding available records.

Creating Custom Feeder Strategies

Why Create Custom Feeders?

While built-in feeders are versatile, they may not cater to every unique testing requirement. For instance, scenarios requiring data fetched in real-time from APIs or databases, or dynamically generated inputs, demand custom solutions. Custom feeders provide the flexibility to:

  • Fetch real-time data from external systems.
  • Handle conditional or scenario-specific data requirements.

Steps to Implement Custom Feeders

Creating a custom feeder involves defining how the data is sourced, processed, and provided to the script. Here’s a step-by-step guide:

Identify Data Requirements

Determine the type and structure of data required. For example, testing an e-commerce application might involve product IDs, user details, and payment methods.

Fetch or Generate Data

Use Scala functions to fetch data from external systems (e.g., APIs, databases) or generate it dynamically using algorithms or predefined patterns.

Format the Data

Ensure the data aligns with Gatling’s feeder format. Feeders typically return a map of key-value pairs, where keys correspond to placeholders in the script.

Integrate with the Script

Use the custom feeder in your Gatling script. For example:

val customFeeder = Iterator.continually {
  Map("username" -> s"user${System.currentTimeMillis()}", "password" -> "securePass123")
}

Test and Debug

Validate the custom feeder to ensure data accuracy and compatibility with the application under test.

Dynamic Data Handling in Gatling Scripts

Incorporating Dynamic Data with Feeders

Dynamic data enhances the realism of Gatling scripts by replicating the variations seen in real-world scenarios. For example, instead of all virtual users logging in with the same credentials, dynamic data allows each user to have a unique login ID and password. This approach uncovers potential issues like database constraints or authentication errors.

Dynamic Data can be incorporated by:

  • Pulling data from APIs in real-time.
  • Using randomization functions to generate test inputs.
  • Accessing pre-processed datasets that simulate real-world usage patterns.

Transforming Static Data into Dynamic Inputs

Static datasets can be enriched with transformations to introduce variability. For instance, appending timestamps to usernames or randomizing numeric inputs can simulate diverse user behaviors without requiring a massive data repository.

Advanced Techniques for Custom Feeders

Leveraging External Data Sources for Feeders

One of the most powerful aspects of custom feeders is their ability to fetch data from external sources. Examples include:

1. Fetching Data from APIs

You can fetch fresh information from other places to make your tests feel more real with current data. Gatling allows you to create custom feeders that retrieve data from APIs using HTTP requests.

val apiFeeder = Iterator.continually {
  val apiResponse = http("Retrieve API Data")
    .get("https://api.example.com/user-profile")
    .check(status.is(200))
    .check(jsonPath("$.userId").saveAs("userId"))
    .check(jsonPath("$.userName").saveAs("userName"))

  // Return the fetched data as a map
  Map("userId" -> apiResponse("userId").as[String], "userName" -> apiResponse("userName").as[String])
}

In this example, data is fetched from an API and used in subsequent requests to simulate real-time user behavior.

2. Querying Data from Databases

We can query a database directly to retrieve fresh, context-specific data. This is useful when we need to test with data that exists in the system being tested, such as user accounts, product details, or transaction history.

import java.sql.DriverManager

val dbFeeder = Iterator.continually {
  val connection = DriverManager.getConnection("jdbc:mysql://localhost/testdb", "user", "password")
  val stmt = conn.createStatement()
  val resultSet = stmt.executeQuery("SELECT userId, userName FROM users ORDER BY RAND() LIMIT 1")
  
  if (resultSet.next()) {
    Map("userId" -> resultSet.getString("userId"), "userName" -> resultSet.getString("userName"))
  } else {
    Map("userId" -> "default", "userName" -> "default")
  }
}

3. Reading Data from Files (CSV/JSON)

For large datasets or pre-existing static data, we can read data from external files such as CSV or JSON files. Gatling provides built-in support for CSV feeders, and we can also use custom feeders for other formats like JSON.

Example:

  • CSV Feeder
val csvFeeder = csv("data/users.csv").circular
  • JSON Feeder (Custom Implementation)
import io.circe.parser._

val jsonFeeder = Iterator.continually {
  val jsonData = io.Source.fromFile("data/users.json").getLines.mkString
  val json = parse(jsonData).getOrElse(Json.Null)
  
  // Retrieve values from the JSON
  val userId = json.hcursor.downField("user").get[String]("id").getOrElse("defaultId")
  val userName = json.hcursor.downField("user").get[String]("name").getOrElse("defaultName")
  
  Map("id" -> userId, "name" -> userName)
}

Conclusion

Leveraging external data sources for feeders allows for richer, more realistic testing scenarios, ensuring that your load tests simulate real-world usage patterns and handle dynamic data. Whether pulling from APIs, querying databases, or reading from files, Gatling enables seamless integration with external data sources.

Picture of Rahul Sharma

Rahul Sharma

Leave a Comment

Your email address will not be published. Required fields are marked *

Suggested Article

Scroll to Top