How do you point one Karate suite at a different environment, and what does `karate.env` hold inside `karate-config.js` when nothing has set it?
answer
- One value steers the whole suite
- A system property, or the runner builder
- It names the extra config file
- Readable inside the config file too
- Unset means null, not a default name
basics
~10 sSet the karate.env system property, for example -Dkarate.env=qa, or call karateEnv("qa") on the runner builder. Karate then also looks for karate-config-qa.js and exposes the name as karate.env, which is null when nothing set it.
solid answer
~40 sYou do not change the features — you change one value. Set the `karate.env` **system property** (`-Dkarate.env=qa`) or call `karateEnv("qa")` on the runner builder, and Karate does two things with it. First, it looks for `karate-config-qa.js` next to your `karate-config.js` and evaluates it last, so its keys override. Second, it exposes the name as `karate.env`, readable inside every config file and every step, so one config file can branch on it instead. When nothing sets it, `karate.env` is **`null`** — not `"dev"`, not an empty string — and no environment-specific file is looked for at all. `karate.config.dir` moves the directory Karate searches for these files, which is how a project keeps its config outside the default location.
code
javascript · 9 linesfunction fn() {
var env = karate.env || 'dev'; // karate.env is null when nothing set it
karate.log('running against env:', env);
var config = { baseUrl: 'http://localhost:8080' };
if (env == 'qa') {
config.baseUrl = 'https://qa.example.com';
}
return config;
}go deeper
Recall the switch itself: pass -Dkarate.env=qa, and Karate picks up karate-config-qa.js on top of the common config. No feature file changes.
Explain both effects of setting it — it names the extra config file and it becomes a readable value — and know that unset means null, so no environment file is even looked for.
Guard the null case and make the resolved environment visible in the run output, because a silently empty config fails far from its cause and a mis-set one can point a suite at the wrong host.
Set the policy for how environments are named and where their config lives, so that a reader of any pipeline can answer what a given run was pointed at without opening a runner class.
## The one value that steers everything Aiming a Karate suite at another host is deliberately a one-value change. You set `karate.env`, and nothing in the feature files moves. Two ways to set it, both available wherever Karate runs: - **The `karate.env` system property** — `mvn test -Dkarate.env=qa`. This is the CI-friendly form; the build passes it and no code changes. - **The runner builder** — `karateEnv("qa")` on the `Runner` builder, for a runner class that always targets one environment. ## What Karate does with the value Setting it has exactly two effects, and it is worth keeping them separate in your head: 1. **It extends the config chain.** Karate looks for `karate-config-<env>.js` — `karate-config-qa.js` for `qa` — and evaluates it *after* `karate-config.js`, so any key it returns overrides the common one. 2. **It exposes the name.** `karate.env` is readable inside every config file and inside any step, so a single `karate-config.js` can branch on it without a second file existing at all. Those two effects give you two legitimate styles, and teams pick one: | Style | Shape | Suits | |---|---|---| | One file, branch inside | `karate-config.js` switches on `karate.env` | a handful of environments, few differences, everything visible in one place | | A file per environment | `karate-config.js` plus `karate-config-qa.js`, `karate-config-prod.js` … | many differences per environment, or secrets you want to keep out of the shared file | ```javascript // one-file style function fn() { var env = karate.env; var config = { baseUrl: 'http://localhost:8080' }; if (env == 'qa') { config.baseUrl = 'https://qa.example.com'; } else if (env == 'prod') { config.baseUrl = 'https://example.com'; } return config; } ``` ## `karate.env` is null until you set it This is the detail interviewers actually probe. With nothing set, `karate.env` inside `karate-config.js` is **`null`**. It does not default to `dev`, or `local`, or the empty string. Two consequences: - A `switch (karate.env)` with no `default` branch silently produces the empty config for a local run, and the suite fails much later on an undefined variable. - **No environment-specific file is looked for at all.** Karate only goes hunting for `karate-config-<env>.js` once `karate.env` has a value, so a local run never picks one up by accident. The idiomatic guard is to give the local case a real name in the config file itself: ```javascript function fn() { var env = karate.env || 'dev'; // never leave it null past this line // … } ``` ## Where Karate looks for the files By default the config files are looked for on the classpath, which for a typical Maven layout means the test resources root. The `karate.config.dir` system property overrides that directory, and the environment-specific file is looked for in the **same** place as `karate-config.js` — the two travel together. That matters for two real situations: - **A standalone run outside a build** has no build-supplied classpath to fall back on, so a project whose config does not sit under the working directory quietly gets no config variables at all. - **A repository with several suites** can keep one config directory per suite and point at it per run. ## Practical guidance - Prefer passing `-Dkarate.env=...` from the build over hard-coding an environment into a runner class — a hard-coded runner is the thing that eventually runs the destructive suite against the wrong host. - Keep the environment names short and identical to the file suffixes; `karate-config-qa.js` and an env of `QA` do not match. - Print the resolved environment once per run. `karate.log('env:', karate.env)` in the config file costs nothing and turns an entire class of "which host did this actually hit" questions into a log line. - Do not put secrets in the shared `karate-config.js`. That is precisely the case the per-environment file exists for, and it is the file teams routinely keep out of version control. ## What setting `karate.env` does *not* do Three things are commonly attributed to it that it does not do, and separating them is most of the understanding: - **It does not select scenarios.** Filtering which scenarios run for an environment is the job of the environment tags on a scenario, which read the same value but are a separate mechanism. Setting `karate.env` alone changes configuration, not selection. - **It does not move the config directory.** The lookup location is governed by `karate.config.dir`. A run can point at a different config directory without changing environment, and vice versa. - **It does not reach into a called feature.** The config chain runs for top-level scenarios only, so calling a feature that happens to sit beside a `karate-config-prod.js` does not load that file. The environment is a property of the run, decided once at its entry point. ## The failure mode to expect The characteristic symptom of a misconfigured environment is not an error but a **quiet substitution**. The env file is not found, no warning stops the run, and every scenario proceeds against whatever the common config supplied — usually localhost. Tests then fail on connection refused, or worse, pass against a stale local service while everyone believes they exercised QA. Two cheap defences: 1. **Assert the target once.** A smoke scenario that asserts `baseUrl` matches the environment you asked for turns a silent substitution into a single, clearly named failure. 2. **Echo the resolved value.** `karate.log('env:', karate.env)` in the config file puts the answer in every run's output, so the question is answered from the log rather than from guesswork.
- A teammate reports that their Karate `karate-config-qa.js` is never picked up. What do you check first?Whether `karate.env` is actually reaching the run. Karate looks for the environment-specific file only when `karate.env` holds a value, so an unset or misspelled property means the file is never even searched for — no warning, no error. Then check that the suffix matches the value exactly, and that the file sits in the same directory as `karate-config.js`.
- Would you branch on `karate.env` inside one config file, or keep a file per environment?Branch inside one file while the differences are a handful of values — everything a reader needs is in one place. Split into per-environment files once the differences grow, or once one environment needs values you do not want in the shared file. The two styles compose: the common file can still hold everything shared and the env file only the deltas.
saying these in an interview costs you the question
- Says karate.env defaults to dev when unset
- Thinks you must edit feature files to change environment
- Believes the env file loads regardless of karate.env
- Assumes karate.env is only readable from Java, not JavaScript
- Hard-codes the environment into a runner class as the norm