skip to content

Glue-Free Execution

A feature file here is the whole test: the keywords that build and fire an HTTP call ship with the tool, so no second layer of code binds a sentence to a method. Interviewers probe the trade.

on this pageshow

explore

questions

13

A Karate scenario reads `Given url 'https://api.example.com'`, `And path 'cats'`, `And request { name: 'Billie' }`, `When method post`, `Then status 201`. Which of those steps actually puts a request on the wire, and what does the `status` step do?

level: juniorimportance: must knowfreq 84%

answer

  1. Only one step opens a socket
  2. The rest just accumulate state
  3. Look for the verb keyword
  4. method fires, status asserts afterwards

basics

~20 s

The method step sends it. The url, path and request steps only accumulate state on Karate's request builder; method is what fires the call. The status step then asserts the response code and fails if it is anything else.

solid answer

~50 s

Karate assembles one HTTP request out of separate steps. `url`, `path`, `param`, `header`, `cookie`, `request`, `form field` and `multipart field` each write into a per-scenario request builder and send nothing at all. **`method <verb>` is the trigger** — it records the verb and immediately invokes the HTTP client, so a scenario that never reaches a `method` step never makes a call. The verb is matched case-insensitively, and `method verb` evaluates a variable that holds it. `soap action` is the one other keyword that fires a call itself: it sets `SOAPAction`, forces `text/xml` and performs the POST. Once a response is back Karate auto-binds `response`, `responseStatus`, `responseHeaders` and `responseTime`, and `status 201` is a shortcut assertion on the status. It parses a literal number, so an expected code held in a variable needs `match responseStatus == expected` instead.

code

gherkin · 9 lines
gherkin
Scenario: create a cat
  Given url 'https://api.example.com'
  And path 'cats'
  And header Accept = 'application/json'
  And request { name: 'Billie', type: 'LOL' }
  When method post
  Then status 201
  And match response.name == 'Billie'
  And match responseStatus == 201

go deeper

for a junior

Remember the shape: everything above the method step is setup, the method step sends, and status plus match check what came back.

for a middle

Be able to explain that a single per-scenario request builder holds the state and that method both sets the verb and invokes the client synchronously.

for a senior

In review, count the method and soap action steps to count the real HTTP calls; that catches scenarios that fire twice or never fire at all.

for a principal

The tradeoff worth naming is that a keyword-is-the-implementation model removes the glue layer but also removes the seam where teams used to put cross-cutting request policy.

## The scenario is one request, spelled out in steps A Karate `Scenario` does not build a request object that you then hand to a client. Each built-in HTTP keyword writes into a request builder that lives for the duration of the scenario, and that builder holds the state until something fires it. | Keyword | What it writes | Sends anything? | |---|---|---| | `url` | the base URL | no | | `path` | one or more path segments, appended | no | | `param` / `params` | query-string entries | no | | `header` / `headers` | request headers | no | | `cookie` / `cookies` | request cookies | no | | `request` | the request body | no | | `form field` / `multipart field` / `multipart file` | a form body | no | | `method` | the verb — **and invokes the client** | **yes** | | `soap action` | `SOAPAction` + `text/xml` — **and posts** | **yes** | | `status` | nothing; asserts the response code | no | There is no step-definition class behind any of these. The keyword *is* the implementation, which is why a Karate project has no glue package to write, register or point a runner at. ## What `method` actually does The `method` step does two things in order: it records the verb on the builder, then it invokes the HTTP client right there, synchronously, before the next step runs. 1. The text after `method` is upper-cased and checked against the nine standard verbs — GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS, CONNECT, TRACE — so `method get`, `method GET` and `method Get` are the same step. 2. If it is not one of those, Karate evaluates the text as an expression, which is how `method verb` works when `verb` holds `'post'`. 3. If the request has no URL at all, the call fails before it leaves the process with a complaint that the request is incomplete. 4. If the scenario never reaches a `method` step, nothing is sent and `response` is never bound — a `match response ...` afterwards fails on an undefined variable, not on a bad payload. That last point is the practical consequence of the design: a scenario that assembles a perfect request and forgets the `method` step is not a failing HTTP test, it is a test that made no HTTP call. ## `status` is an assertion, not a label `status 201` compares the response status to that number and fails the step when they differ. Two details matter: - **The number must be a literal.** The step parses the text after `status` as an integer, so `status expectedCode` fails on the step itself — it never reaches a comparison. - **It only handles one exact code.** For a variable, a range, or a set of acceptable codes, drop the shortcut and assert on the auto-bound variable: `match responseStatus == expected`, or `match [200, 201] contains responseStatus`. ## The keyword that fires without saying `method` `soap action` is easy to misread as a header-setting step. It sets the `SOAPAction` header, forces the content type to `text/xml`, **and then performs the POST itself**. Writing `When method post` after it does not "complete" the call; it sends a second one, this time with the SOAPAction header and body already cleared. ```gherkin Scenario: soap action fires the call by itself Given url 'https://api.example.com/services/balance' And request read('query-balance.xml') When soap action 'QueryUsageBalance' Then status 200 And match /Envelope/Body/Result/Code == 'OK' ``` ## What is bound once the response is back Every call rebinds four variables, and they are what the rest of the scenario asserts on: - `response` — the body, already converted to a map, a list, an XML node, a string or bytes according to its content type. - `responseStatus` — the status code as a number. - `responseHeaders` — a map of header name to a list of values. - `responseTime` — elapsed milliseconds for that call. Because they are rebound on every call, they always describe the **most recent** request in the scenario. If you need a value from an earlier call, capture it with `def` before you fire the next one. ## Reading a scenario back The useful habit is to scan a Karate scenario for its `method` and `soap action` steps first: that tells you how many HTTP calls it makes. Everything above a `method` step is setup for that one call, and everything below it up to the next `method` step is assertion on that one response.

  • Is `method` the only keyword in a Karate feature file that sends a request?
    No. `soap action` fires one too: it sets the `SOAPAction` header, sets `Content-Type: text/xml`, and performs a POST itself. That is why you never write `method post` after it — doing so sends a second, emptied request. Every other HTTP keyword only writes into the request builder.
  • How do you assert a status code that is not a fixed literal?
    Use the auto-bound `responseStatus` variable with `match`. `status` parses the text after it as an integer, so `status expectedCode` fails on the step itself. Write `match responseStatus == expectedCode`, or for a set of acceptable codes, `match [200, 201, 202] contains responseStatus`.
  • What happens if a scenario sets `path` and `request` but no `method` step?
    No HTTP call is made. The builder simply keeps that state, and `response`, `responseStatus`, `responseHeaders` and `responseTime` are never bound, so the first assertion that touches `response` fails on an undefined variable rather than on a payload mismatch.

saying these in an interview costs you the question

  • Says the url step is what sends the request
  • Thinks each HTTP keyword makes its own call
  • Expects a step-definition class behind method
  • Writes method post after soap action, firing twice
  • Writes status expectedCode with a variable name
  • Treats Then status 200 as documentation, not an assertion
open as a page

In a Karate feature file, what does a step that begins with a bare `*` — such as `* def id = 5` — mean, and what changes if you write `Given`, `When` or `Then` in front of it instead?

level: juniorimportance: must knowfreq 78%

basics

~20 s

Nothing changes. Karate accepts six step prefixes - the bare asterisk plus Given, When, Then, And and But - and treats all six identically. The prefix never reaches the code that decides what a step does; it is read back only afterwards, by the report and the rest of the output.

open as a page

In a Karate `Scenario Outline` step, what is the difference between writing `<name>` and `'#(name)'`, and which one preserves the column's type?

level: middleimportance: must knowfreq 52%

basics

~20 s

In Karate, <name> is a text substitution: the raw cell text is spliced into the step before it runs. '#(name)' is an embedded expression evaluated at run time against the bound variable, so the value keeps its type.

open as a page

In a Karate feature file, what turns an `Examples:` table into a dynamic one — so its rows come from `read('cats.json')` or `karate.setup()` instead of being typed out — and what must that cell evaluate to?

level: middleimportance: must knowfreq 60%

basics

~20 s

Karate treats an Examples table as dynamic only when it is a single cell: one column and one row, the header, with nothing under it. That cell is evaluated as JavaScript and must return a list of objects or a generator function.

open as a page

In a Karate `Examples:` table, what does appending `!` to a column header do, and what type does that column's value have without it?

level: middleimportance: must knowfreq 54%

basics

~20 s

A trailing ! on a Karate Examples column header makes each cell evaluate as a JavaScript value — number, boolean, or inline JSON. Without it the cell stays a plain string, and a blank cell becomes null.

open as a page

A Karate scenario sets `url`, `path 'cats'`, `header Authorization = token` and `request`, then fires `method get`. Which of those four settings still apply to the next `method` step in the same scenario, and how do you make the others persist?

level: middleimportance: must knowfreq 66%

basics

~20 s

Only the url survives. After every call Karate clears the path, query params, headers, cookies, request body, multipart parts and any retry-until condition. To keep a header or cookie across calls, set it with configure headers or configure cookies instead.

open as a page

In a Karate feature file the step prefix (`*`, `Given`, `Then`) selects nothing, so what actually decides what `* retry until responseStatus == 200` does - and why does `* cats[id] = request` run as JavaScript instead?

level: middleimportance: must knowfreq 61%

basics

~20 s

The leading keyword after the prefix decides. Karate reads a one- or two-word keyword - retry until is two words - and runs its built-in. When that first token carries punctuation instead, the whole line is evaluated as JavaScript.

open as a page

Inside a Karate `Scenario Outline`, what are the `__row` and `__num` variables bound to, and what else does each `Examples:` column give you?

level: juniorimportance: should knowfreq 46%

basics

~10 s

In Karate, __row holds the whole current Examples row as an object, __num holds that row's index counting from zero, and every column is also bound as a variable under its own name.

open as a page

In a Karate feature file, what body does each of `request`, `form field` and `multipart field` build, and what `Content-Type` does each send when you never set that header yourself?

level: middleimportance: should knowfreq 47%

basics

~20 s

request sets the body as-is and Karate infers the Content-Type from its data type: application/json for a map or list, text/plain for a string, application/xml for an XML node, octet-stream for bytes. form field builds a urlencoded body, multipart field a multipart/form-data one.

open as a page

In a Karate feature file, where must a `retry until` step sit relative to the `method` step, how many times does Karate call the endpoint by default, and what is waited between attempts?

level: middleimportance: should knowfreq 52%

basics

~20 s

retry until must come before the method step it applies to. The defaults are three attempts in total with a 3000 millisecond pause between them, and both are changed with configure retry set to a count and interval.

open as a page

A Karate `Scenario Outline` is driven by a single-cell `Examples:` table holding `read('users.csv')`, and the step `match __row.age == 30` fails. Why, and what are your options?

level: seniorimportance: should knowfreq 38%

basics

~20 s

Karate's CSV reader hands back every field as a string, so __row.age is '30', not 30, and a strict match against a number fails. CSV carries no types, and a dynamic table has no ! header to hint one.

open as a page

A Karate step `* path 'search?q=cats'` produces a request to `/search%3Fq=cats` and the endpoint returns an empty result instead of failing. Why does Karate encode the question mark, and how should a query string and a multi-segment path be written instead?

level: seniorimportance: should knowfreq 41%

basics

~20 s

The path keyword treats its argument as path segments and percent-encodes each one, so a question mark becomes %3F and lands in the path rather than starting a query string. Query parameters belong in the param keyword, or in the url text itself.

open as a page

A Karate scenario fails on the step `* count = count + 1`, and the project has no step-definition classes that could be missing. Given that Karate dispatches on the leading keyword and that this line does not qualify for the JavaScript escape hatch either, what went wrong and what is the fix?

level: seniorimportance: should knowfreq 44%

basics

~20 s

The bare word count is read as the step's keyword, and Karate has no such keyword. It is not punctuated either, and no parenthesised call follows it, so the JavaScript path is not taken. Use def instead: write a def count = count + 1 step.

open as a page