skip to content

In Gatling's scenario DSL, how does asLongAs differ from doWhile, and what do asLongAsDuring and doWhileDuring add?

level: middleimportance: should knowfreq 45%

answer

  1. One tests first, the other tests last
  2. A do-while always runs its body once
  3. The During pair adds a clock bound
  4. asLongAs before the body, doWhile after
  5. Either bound ends asLongAsDuring

basics

~20 s

asLongAs tests its condition before each iteration, so the body can run zero times; doWhile tests it after, so the body always runs at least once. The During variants add a maximum duration that also ends the loop.

solid answer

~40 s

Both blocks repeat a chain while a condition holds, and they differ only in when the condition is read. `asLongAs(condition)` reads it before each iteration, so a condition that is already false means the body never runs. `doWhile(condition)` reads it after the body, so the first pass is unconditional and the body always runs at least once. `asLongAsDuring(condition, duration)` and `doWhileDuring(condition, duration)` keep that difference and add a second bound: the block also ends when the duration elapses, whichever comes first. The condition is a Gatling EL string resolving to a boolean or a function from the session to a boolean. The time-bounded pair is what you use when the system under test controls the condition and might never flip it.

code

java · 7 lines
java
ScenarioBuilder scn = scenario("poll job status")
  .doWhile(session -> !session.getBoolean("finished")).on(
    http("status").get("/jobs/42")
  )
  .exec(
    http("result").get("/jobs/42/result")
  );

go deeper

for a junior

Be ready to name the two condition-driven loops and say which one always runs its body once.

for a middle

Explain that the only difference is whether the condition is evaluated before or after the body, and that the During variants add a second, independent bound.

for a senior

Show that you would not ship a condition-driven loop whose condition the system under test owns without a duration bound on it.

for a principal

Own the convention for polling in a suite: which block, what bound, and what the run should record when the bound is what ended the loop rather than the condition.

## One difference: when the condition is read `asLongAs` and `doWhile` wrap the same thing — a chain of actions that repeats while a condition holds — and they take the same arguments. The only difference is **when Gatling evaluates the condition**. - **`asLongAs(condition)`** evaluates it **before** each iteration. If the condition is already false when the user arrives, the body never runs. This is an ordinary `while` loop. - **`doWhile(condition)`** evaluates it **after** each iteration. The first pass is unconditional, so the body always runs **at least once**. This is a `do ... while` loop. Internally that is a single flag on the loop type: Gatling forces the continue-condition to `true` while the loop counter is still 0 for `doWhile`, and only starts asking the real condition from the second pass onwards. ## Adding a clock A condition-only loop has an obvious failure mode: if the condition never turns false, the virtual user never leaves. The `...During` pair closes that hole by adding a maximum duration, and the loop ends when **either** bound is reached. | block | what ends it | condition read | |---|---|---| | `asLongAs(cond)` | the condition turning false | before each iteration | | `doWhile(cond)` | the condition turning false | after each iteration | | `asLongAsDuring(cond, d)` | the condition **or** the elapsed time | before each iteration | | `doWhileDuring(cond, d)` | the condition **or** the elapsed time | after each iteration | | `during(d)` | the elapsed time only | not applicable | | `forever()` | nothing inside the block | not applicable | The duration argument takes the same forms as `during`'s: a bare number meaning seconds, a `java.time.Duration` in Java and Kotlin, a Scala duration literal, an object literal in JavaScript and TypeScript, an EL string, or a function. ## What the condition can be For all four blocks the condition is one of: 1. A **Gatling EL string** that resolves to a boolean, such as `"#{shouldContinue}"`. 2. A **function** from the session to a boolean — `session -> !session.getBoolean("finished")` in Java, `session => !session("finished").as[Boolean]` in Scala. A literal boolean is accepted too, but a constant condition makes the loop either a `forever` or a no-op, so it is rarely what you want. ## Spelling per SDK Java, Kotlin, JavaScript and TypeScript attach the body with `.on(...)`: ```java asLongAs(session -> !session.getBoolean("finished")).on( http("status").get("/jobs/42") ); ``` Scala puts the body in a second parameter list: ```scala asLongAs(session => !session("finished").as[Boolean])( http("status").get("/jobs/42") ) ``` Both families also accept an optional counter name, and the two `asLongAs` variants plus `doWhileDuring` accept an `exitASAP` flag that controls whether the loop may break part-way through an iteration. ## Choosing between them - **A polling loop that must issue at least one request** — `doWhile` or `doWhileDuring`. The first call is what produces the state the condition reads, so testing before the body would exit on an unset attribute. - **A loop guarding work that may already be unnecessary** — `asLongAs`. If a previous step already satisfied the condition, you want zero iterations, not one. - **Anything driven by a condition the system under test controls** — one of the `...During` forms. A backend that never returns the terminal state should cost you a bounded wait, not a virtual user stuck for the length of the run. - **A fixed number of passes** — neither; use `repeat`, which needs no condition at all. ## Traps - **Expecting `asLongAs` to run its body once "to get started".** It will not; use `doWhile`, or seed the attribute before the loop. - **Treating `doWhileDuring` as condition-only.** The duration is a hard second bound, and it can end the loop while the condition is still true. - **Using `forever()` with nothing else bounding the user.** It is legitimate, but only when something outside the block ends the run. - **Assuming the condition is re-read mid-iteration — or assuming it never is.** Whether the condition is re-read inside the body, rather than only at the loop boundary, is exactly what the `exitASAP` argument switches on, and the defaults are not uniform: `asLongAs` is off in every SDK and `doWhile` has no such argument at all, but `asLongAsDuring` and `doWhileDuring` default to **on** in the Scala core DSL and **off** in the Java API that Kotlin, JavaScript and TypeScript sit on. Pass the flag explicitly when the answer matters. - **Naming the same counter in two nested loops.** Each block needs its own counter name; sharing one corrupts the bookkeeping of both. - **Reaching for `doWhile` when the real requirement is a timeout.** A do-while still depends on the condition eventually flipping; only the duration argument guarantees the user gets out. Interviewers rarely ask you to recite all eight loop blocks. They ask which one you would reach for when a job endpoint has to be polled until it reports completion, and then whether your answer still terminates when the job never completes. The pairing of a post-evaluated condition with a duration bound is the answer that survives both halves of that question.

  • Which of these blocks runs its body when the condition is already false on entry?
    `doWhile` and `doWhileDuring`. Both evaluate the condition only after an iteration has run, so the first pass is unconditional. `asLongAs` and `asLongAsDuring` evaluate before the body and will run it zero times.
  • How do you stop an asLongAs loop whose condition might never turn false?
    Use `asLongAsDuring` instead and give it a duration. The block then ends on whichever bound arrives first, so a backend that never reports completion costs you a bounded wait rather than a virtual user parked for the length of the run.

A doorman who checks IDs on the way in can turn everyone away; one who checks on the way out has already let each person spend an evening inside. asLongAs is the first doorman, doWhile the second.

saying these in an interview costs you the question

  • Expecting asLongAs to run its body at least once
  • Believing doWhileDuring ignores its duration while the condition holds
  • Using forever with nothing else bounding the user
  • Reading doWhile as a countdown rather than a condition
  • Sharing one counter name between two nested loops