Skip to main content

RUNNING TESTS

Command Line

Karate v2 has a first-class CLI — karate run — alongside full Maven and Gradle integration via JUnit 6. Pick the entry point that fits your project; all three share the same underlying Runner API.

The familiar -Dkarate.options="..." and -Dkarate.env=... system-property overrides from v1 are supported in v2, so Maven/Gradle teams upgrading from v1 keep their "hard-code defaults in a Runner class, override from CI" workflow without code changes.

The karate run CLI

The simplest way to run tests — no Maven, no Gradle, no Java class needed. See Standalone Execution for installation.

Command Line
# Run all features in a directory
karate run features/

# Run a single feature file
karate run features/users.feature

# Run a specific scenario by line number
karate run features/users.feature:25

# Run multiple paths (repeatable -P, or comma-separated --path a,b)
karate run -P features/smoke -P features/regression

# Filter by tag, 4 threads, QA environment
karate run -t @smoke -T 4 -e qa features/

Common Flags

FlagDescription
-P, --path <path>Feature file or directory — repeatable and/or comma-separated
-t, --tags <expr>Tag expression (e.g. @smoke, ~@slow) — repeatable
-T, --threads <n>Parallel thread count
-e, --env <name>Karate environment (karate.env)
-n, --name <name>Scenario name filter (exact, whitespace-trimmed); bypasses tag filters
-o, --output <dir>Report output directory
-g, --configdir <dir>Directory containing karate-config.js
-f, --format <formats>Output formats: html, cucumber:json, junit:xml, karate:jsonl (prefix ~ to disable)
-D, --dryrunParse but don't execute

Run karate run --help for the full list.

Project File: karate-pom.json

For CLI users, karate-pom.json is a JSON project file that persists your run settings — analogous to pom.xml but for Karate. When present in the working directory, karate run loads it automatically.

karate-pom.json
{
"paths": ["classpath:com/comp/commission", "classpath:com/comp/statement"],
"tags": ["@smoke", "~@slow"],
"env": "qa",
"threads": 5,
"output": {
"dir": "target/karate-reports",
"cucumberJson": true
}
}

CLI flags override pom values. Use --no-pom to ignore it.

Maven Execution

Java teams use the karate-junit6 dependency and drive runs through a JUnit 6 test class. Standard mvn test discovers and runs them.

Command Line
# Run all JUnit tests (including Karate runners)
mvn test

# Run a specific Karate runner class
mvn test -Dtest=UsersTest

# Run a specific test method
mvn test -Dtest=UsersTest#smokeTests

# Override the environment (karate.env)
mvn test -Dkarate.env=qa

# Override tags from CI without changing the Runner class
mvn test -Dtest=UsersTest -Dkarate.options="--tags @smoke"

# Multiple overrides in one string (v1-compatible)
mvn test -Dtest=UsersTest -Dkarate.options="--tags @smoke --env qa --threads 4"

JUnit 6 Runner Class

UsersTest.java
import io.karatelabs.junit6.Karate;
import org.junit.jupiter.api.DynamicNode;

class UsersTest {

@Karate.Test
Iterable<DynamicNode> testUsers() {
return Karate.run("classpath:users").relativeTo(getClass());
}

@Karate.Test
Iterable<DynamicNode> testSmoke() {
return Karate.run("classpath:users")
.tags("@smoke")
.threads(4)
.karateEnv("qa");
}

@Karate.Test
Iterable<DynamicNode> testMultiplePaths() {
return Karate.run("classpath:com/comp/commission", "classpath:com/comp/statement")
.tags("@smoke");
}
}

Karate.run(...) accepts varargs — use this when you want multiple paths baked into the Runner class. For ad-hoc overrides from CI without changing the class, use -Dkarate.options=... instead.

System-Property Overrides (CI pattern)

You do not need any wiring in your Runner class. Karate picks up these system properties automatically at parallel() time and overrides Builder values before the run:

SyspropEnv var fallbackEffect
karate.optionsKARATE_OPTIONSFull option string using the karate run CLI grammar — paths, -P, tags, threads, env, -n, configdir, output, dryrun, formats
karate.envKARATE_ENVKarate environment
karate.config.dirKARATE_CONFIG_DIRDirectory containing karate-config.js
karate.output.dirReport output directory

Example — typical CI invocations against a runner that hard-codes defaults:

Terminal
# Override one dimension
mvn test -Dtest=UsersTest -Dkarate.env=qa

# Override multiple in one karate.options string
mvn test -Dtest=UsersTest -Dkarate.options="--tags @smoke --threads 4 --env qa"

# Narrow to specific features for a rerun
mvn test -Dtest=UsersTest -Dkarate.options="classpath:features/login.feature:42"

Precedence (highest → lowest): karate.options sysprop > KARATE_OPTIONS env > individual karate.* sysprops > individual KARATE_* env vars > Runner.Builder values > karate-pom.json > defaults. If a malformed karate.options string is passed, it's logged at WARN and ignored — the run proceeds with Builder defaults.

Paths with spaces

The karate.options string is tokenized POSIX-shell-style, so inner quotes survive and whitespace is respected:

Terminal
# Multiple paths that contain spaces — use -P with inner double quotes,
# and protect the whole sysprop value with outer single quotes
mvn test -Dtest=UsersTest '-Dkarate.options=-P "src/features/happy path" -P "src/features/edge cases"'

Single vs double quotes follow shell rules: single quotes around the -D... value stop the outer shell from interpreting the inner doubles; inside the sysprop value, double quotes group the path tokens with whitespace.

Gradle Execution

Gradle integration uses the same JUnit 6 runner class. Forward karate.* system properties to the test JVM so the overrides above work from the command line:

build.gradle
test {
useJUnitPlatform()
systemProperties System.properties.findAll { k, v ->
k.toString().startsWith('karate.')
}
outputs.upToDateWhen { false }
}
Command Line
# Run all tests
./gradlew test

# Run a specific Karate runner class
./gradlew test --tests UsersTest

# Override environment
./gradlew test -Dkarate.env=staging

# Override tags and env from CI (no code change)
./gradlew test -Dkarate.options="--tags @smoke --env qa"

Filtering & Configuration

By Tag

Tag expressions work identically across CLI, Maven, and Gradle. ~ means "not". Comma means OR; repeated --tags means AND.

Command Line
# Run scenarios tagged @smoke
karate run -t @smoke features/

# Exclude @slow
karate run -t ~@slow features/

# Either @smoke OR @regression
karate run -t @smoke,@regression features/

# @smoke AND @api
karate run -t @smoke -t @api features/

See Tags for expression syntax.

By Scenario Line or Name

Terminal
# By line number — bypasses tag filters (great for debugging)
karate run features/users.feature:15

# By scenario name — exact match, trimmed on both sides.
# Stable under edits, so IDE plugins use this as a line-independent key.
karate run -n "Create user happy path" features/

# Combine with :LINE to narrow to one row of a Scenario Outline.
karate run -n "Parameterized check" features/outline.feature:9

Both forms bypass tag filters (@ignore, @env) — running a specific scenario always wins. Duplicate scenario names run every match. For a Scenario Outline, the name matches the outline itself and runs all rows.

By Environment

Set karate.env and read it in karate-config.js:

Command Line
# CLI
karate run -e dev features/

# Maven
mvn test -Dtest=UsersTest -Dkarate.env=qa

# Gradle
./gradlew test -Dkarate.env=staging
karate-config.js
function fn() {
var env = karate.env;
var config = { baseUrl: 'https://api-dev.example.com' };
if (env === 'qa') config.baseUrl = 'https://api-qa.example.com';
if (env === 'prod') config.baseUrl = 'https://api.example.com';
return config;
}

Development Patterns

Tight Iteration Loop

Command Line
# Run one failing scenario by line
karate run features/problem.feature:15

# Run WIP tests locally
karate run -t @wip -e local features/

# Dry run — parse only, no HTTP
karate run -D features/

CI: Smoke then Full

CI pipeline
# Fast smoke stage
karate run -t @smoke -T 4 -e ci features/

# Full suite
karate run -T 8 -e ci --format cucumber:json,junit:xml features/

Migrating from v1

Your v1 -Dkarate.options="..." invocations keep working in v2. The option string uses the same shape, and v2 adds a few new flags you can use inside it (notably -P, --path):

v1v2 equivalentNotes
-Dkarate.options="classpath:features/users.feature"UnchangedPositional paths
-Dkarate.options="features/a features/b"Unchanged, or -Dkarate.options="-P features/a -P features/b"-P is new in v2, handy when paths are awkward as positionals
-Dkarate.options="--tags @smoke"UnchangedTag filter
-Dkarate.options="--dryrun"UnchangedDry run
-Dkarate.options="features/x.feature:25"UnchangedLine number targeting
-Dkarate.env=qaUnchangedIndividual env sysprop

If you're building fresh instead of migrating, prefer the karate run CLI — one command, no JUnit runner class needed.

Common Gotchas

  • Tag AND vs OR: comma is OR within one -t, repeated -t is AND.
  • Path with line number bypasses tag filters — intentional, useful for IDE integrations.
  • Gradle must forward system properties: see the build.gradle snippet above.
  • workingDir vs output.dir: output is relative to process cwd, not workingDir. Prefer absolute paths for reports in CI.
  • karate.options paths replace Builder paths: when the sysprop contains paths, they fully replace any paths set in your Runner class (v1 parity). Use this intentionally for CI subsetting.

Next Steps