skip to content

In a Gatling simulation, which built-in feeders read a character-separated file, and where must the file sit for csv("credentials.csv") to resolve?

level: juniorimportance: must knowfreq 70%

answer

  1. data comes from outside the simulation
  2. four delimited builders, plus JSON and sitemap
  3. classpath root, not a project path
  4. csv, ssv, tsv, separatedValues(path, separator)
  5. optional argument is quoteChar, default double quote

basics

~10 s

Gatling ships csv, tsv, ssv and separatedValues for delimited files, plus jsonFile, jsonUrl and sitemap. The path is resolved from your classpath root: src/main/resources or src/test/resources on the JVM, resources in the JavaScript SDK.

solid answer

~40 s

Four built-ins read character-separated files: `csv` (comma), `ssv` (semicolon), `tsv` (tab) and `separatedValues(path, separator)` for anything else. Each takes an optional `quoteChar` argument, defaulting to a double quote — second for `csv`, `ssv` and `tsv`, third for `separatedValues`, whose second argument is the separator itself; there is no `quotes` method. `jsonFile` reads a JSON array of objects, `jsonUrl` fetches one over HTTP, and `sitemap` reads a sitemap XML file but lives in the HTTP DSL rather than core. The argument is a **classpath** path, not a filesystem path: put the file under `src/main/resources`, `src/test/resources`, or `src/gatling/resources` under Gradle, and pass the path relative to that root, so `csv("data/credentials.csv")`. The JavaScript and TypeScript SDK uses a `resources` folder instead. An absolute filesystem path also works when data files ship separately from the simulation.

code

java · 10 lines
java
import io.gatling.javaapi.core.*;

import static io.gatling.javaapi.core.CoreDsl.*;

public class CredentialFeeders {
  FeederBuilder.FileBased<String> commas = csv("data/credentials.csv");
  FeederBuilder.FileBased<String> pipes = separatedValues("data/credentials.txt", '|');
  FeederBuilder.FileBased<String> singleQuoted = csv("data/credentials.csv", '\'');
  FeederBuilder.FileBased<String> compressed = csv("data/credentials.csv.gz").unzip();
}

go deeper

for a junior

Be ready to name the four delimited-file builders and say where the file goes. Reciting csv, ssv, tsv and separatedValues plus the classpath root covers most of what is asked at this level.

for a middle

Explain that the argument is a classpath path resolved when the builder is created, that the optional extra argument is quoteChar rather than the separator, and that sitemap comes from the HTTP DSL.

for a senior

Be able to justify a builder choice for a supplied data file, including when unzip and transform earn their place and what an absolute path buys you when the data ships separately from the artifact.

for a principal

Own the convention across the suite: whether feeder data lives inside the built artifact or beside the load generator, and what that settles about reproducibility, artifact size and how the file reaches every generator.

## What a feeder actually is A **feeder** is a stock of records that virtual users draw on, so that a thousand simulated logins do not all send the same username. The SDK exposes a `feed` method that can be placed wherever `exec` is placed. Every time a virtual user reaches that step it collects one record, and Gatling merges that record's keys into the user's Session as attributes, ready for `#{username}` style interpolation. A record is just a map of names to values; the names come from the source itself — a CSV header line, a JSON object's keys, a sitemap element's tags. ## The character-separated family Four builders read delimited files. They are the same RFC 4180 parser with a different separator baked in: | builder | separator | optional quote-char argument | |---|---|---| | `csv(path)` | comma | `quoteChar`, default `"` | | `ssv(path)` | semicolon | `quoteChar`, default `"` | | `tsv(path)` | tab | `quoteChar`, default `"` | | `separatedValues(path, separator)` | whatever you pass | `quoteChar`, default `"` (third argument, after the separator) | Two things trip people up. `ssv` is **semicolon**-separated, not space-separated. And that optional extra parameter is the **quote character**, not the separator — there is no `quotes` method, so `csv("x.csv", ';')` makes `;` the quote character and leaves the separator a comma. Only `separatedValues` takes a separator argument at all, because it has none baked in: there the separator is the mandatory second argument and `quoteChar` moves to third. The one documented deviation from RFC 4180 is that header fields are trimmed of wrapping whitespace. ## The other file-backed sources * `jsonFile(path)` reads a JSON document whose **root node must be an array**. Each object in that array becomes one record, and its keys become the attribute names. * `jsonUrl(url)` reads the same shape over HTTP instead of off the classpath. * `sitemap(path)` reads a sitemap XML file, turning each `<url>` element into a record carrying `loc`, and `lastmod`, `changefreq` and `priority` where the element has them. It lives in the **HTTP** DSL, not core — `io.gatling.javaapi.http.HttpDsl` for Java and Kotlin, `io.gatling.http.Predef._` for Scala, `@gatling.io/http` for JavaScript and TypeScript — so a simulation that imports only the core DSL will not see it. ## Where the file has to sit The string you pass is a **classpath** path, not a filesystem path. 1. On the JVM SDKs, put the file under `src/main/resources` or `src/test/resources`, or under `src/gatling/resources` when you build with Gradle. 2. In the JavaScript and TypeScript SDK, put it under `resources`. 3. Pass the path **relative to that root**. A file at `src/test/resources/data/credentials.csv` is declared as `csv("data/credentials.csv")`. The documented alternative is an **absolute** filesystem path, which is how you deploy data files separately from the packaged simulation and let them sit on the load generator's own disk. What is not accepted is a path that names your source tree, such as `src/main/resources/data/credentials.csv`: Gatling recognises that prefix and refuses it with a message telling you to drop it. ## What you can chain onto the builder The builder is immutable — every call returns a new one, so keep the value: * `unzip()` for a gzip or zip source, decompressed on the fly. * `transform(...)` to convert a value before the user sees it, because a delimited file yields only `String`s. Java and Kotlin take a `BiFunction<String, T, Object>` over key and value; Scala takes a `PartialFunction[(String, T), Any]` defined only for the keys you want changed. * `recordsCount()` for the number of records, and `readRecords()` for the records themselves. * `shard()`, which slices the data across load generators on Gatling Enterprise and is a no-op anywhere else. In Scala these parameterless calls are written without parentheses — `csv("x.csv").unzip`, not `unzip()` — which is the usual cross-SDK spelling difference rather than a different feature. ## What the record turns into Whatever the source, a record is a map and its keys become Session attributes for that one virtual user. That has two consequences worth stating out loud: * The attribute names are decided by the **data**, not by the simulation. Rename a CSV column and every `#{...}` placeholder that referred to it silently stops resolving. * Values from a delimited file are always `String`. A JSON feeder preserves the document's own types, so a numeric field arrives as a number without any `transform` at all. ## The worked example A login scenario backed by a 200,000-row credentials file is the ordinary case. The file goes to `src/test/resources/data/credentials.csv` with a header line reading `username,password`, the simulation declares `csv("data/credentials.csv")`, and the scenario interpolates `#{username}` and `#{password}` into the login request. Nothing about the row count changes the declaration: size only affects how Gatling loads the file at run start, not how you name it.

  • In Gatling, how do you read a file whose columns are separated by a pipe character?
    Use `separatedValues("data/credentials.txt", '|')`. `csv`, `ssv` and `tsv` are fixed-separator shorthands over exactly the same parser — comma, semicolon and tab. All four accept a further optional argument, `quoteChar`, when the file quotes fields with something other than a double quote.
  • A Gatling CSV feeder hands every column over as a String. How do you turn one column into an Int?
    Chain `transform`. In Java and Kotlin it takes a `BiFunction<String, T, Object>` over the key and the value; in Scala it takes a `PartialFunction[(String, T), Any]` you define only for the keys you want changed, leaving the rest untouched. The JavaScript SDK takes a two-argument function.
  • What does Gatling do with the header line of a CSV feeder file?
    The first line supplies the Session attribute names for every record, and Gatling trims wrapping whitespace from each header field. A `jsonFile` feeder has no header: its root node must be a JSON array, and each object's own keys become the attribute names.

saying these in an interview costs you the question

  • Reading ssv as space-separated values; it is semicolon-separated.
  • Passing src/main/resources/data.csv as the feeder path instead of data.csv.
  • Calling a quotes method to set the quote character; only quoteChar exists.
  • Assuming sitemap comes from the core DSL rather than the HTTP DSL.