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.