Every Karate project starts with Maven. That might feel heavyweight if you were expecting a no-code tool, but Maven's role here is minimal: it downloads the Karate dependency and provides a command (mvn test) to run your feature files. You write one pom.xml once, and after that you never touch Java tooling again — the rest is .feature files and one JavaScript config.
The pom.xml — one dependency
Karate ships everything it needs in a single artifact. Add this to a fresh pom.xml:
<dependencies>
<dependency>
<groupId>com.intuit.karate</groupId>
<artifactId>karate-junit5</artifactId>
<version>1.4.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<testResources>
<testResource>
<directory>src/test/java</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</testResource>
</testResources>
</build>One dependency — no separate HTTP client, no assertion library, no reporting plugin. Karate bundles all of them. The <testResources> block tells Maven to include .feature files and .json files that sit alongside your Java sources in src/test/java.
For the Java version, set <maven.compiler.source> and <maven.compiler.target> to 11 or higher. Karate 1.4 requires Java 11 at minimum; Java 17 is a safe default.
Project structure
The layout this course uses:
karate-tests/
├── pom.xml
└── src/test/java/
├── karate-config.js ← global configuration
└── users/
├── UsersRunner.java ← JUnit 5 runner (3 lines)
├── users.feature ← test feature file
└── test-data.json ← test data (optional)
Feature files live next to the runner class that points at them, inside src/test/java. There is no src/test/resources in a typical Karate project — the <testResources> configuration above makes Maven pick up non-Java files from src/test/java directly.
Organise by API resource or by feature area. A team testing a Users API and an Orders API might have users/ and orders/ packages, each with their own runner and feature files.
The runner class
This is the only Java you write in a Karate project:
package users;
import com.intuit.karate.junit5.Karate;
class UsersRunner {
@Karate.Test
Karate testUsers() {
return Karate.run("users").relativeTo(getClass());
}
}Three lines of code. The @Karate.Test annotation tells JUnit 5 to treat this method as a test entry point. Karate.run("users") finds the users.feature file in the same package. relativeTo(getClass()) resolves the path relative to this runner's location on disk. That's the full extent of Java in test authoring.
To run all feature files in a package (not just one), pass "." instead of a file name: Karate.run(".").
karate-config.js — global configuration
karate-config.js lives at the root of src/test/java/ (not inside a package subfolder). Karate automatically runs it before every feature file and makes the returned object available as variables:
function fn() {
var config = {
baseUrl: 'https://api.staging.myapp.com'
};
var env = karate.env; // set via -Dkarate.env on the command line
if (env == 'production') {
config.baseUrl = 'https://api.myapp.com';
}
return config;
}Inside any feature file, baseUrl is now available without any import:
Scenario: Get all users
Given url baseUrl + '/users'
When method get
Then status 200This is the standard Karate pattern for environment-aware tests. The URL is never hardcoded in the feature file — it comes from config, which can be switched at runtime.
Running tests
From the terminal:
mvn test
With a specific environment:
mvn test -Dkarate.env=production
Running a specific feature file only (by tag):
mvn test -Dkarate.options="--tags @smoke"
From IntelliJ: right-click the runner class → Run, or right-click directly on a .feature file → Run. The Karate IntelliJ plugin adds syntax highlighting and individual scenario run buttons inside .feature files — install it before writing your first test.
The setup flow, step by step
Step 1 of 6
pom.xml
Add the karate-junit5 dependency and the testResources block. Run 'mvn dependency:resolve' to confirm Karate downloads. This is the only Maven setup you'll need for the whole course.
⚠️ Common mistakes
- Forgetting the
<testResources>block. Without it, Maven compiles.javafiles insrc/test/javabut ignores.featurefiles next to them. The runner finds no tests and reports zero executed. This is the most common setup failure for new Karate projects. - Placing
karate-config.jsinside a package subfolder. The file must be at the root ofsrc/test/java/, not insideusers/or any other package. Karate looks for it by classpath root. If it's nested, it won't load, and all yourbaseUrlreferences will fail with an undefined variable error. - Using
karate-junit4when the project expects JUnit 5. The artifact names arekarate-junit4andkarate-junit5— they are not interchangeable. If yourpom.xmlhas JUnit 5'sjunit-jupiterelsewhere, usekarate-junit5. Mixing them produces class-not-found errors at runtime that look unrelated to Karate.
🎯 Practice task
Get a runnable Karate project onto disk. 30–40 minutes.
- Create a new Maven project in IntelliJ with GroupId
com.mycompany.karatetestsand ArtifactIdkarate-tests. Confirm the project structure includessrc/test/java. - Replace the generated
pom.xmlwith the dependency and<testResources>blocks from this lesson. Set Java source/target to17. Click "Load Maven Changes". Runmvn dependency:resolveand confirmkarate-junit5appears in the output. - Create
src/test/java/karate-config.js. Return{ baseUrl: 'https://jsonplaceholder.typicode.com' }. This free fake API works without authentication. - Create the package
usersundersrc/test/java. AddUsersRunner.java— copy the three-line example above, changing the package tousers. - Create
users/users.featurewith a single scenario: GET/users, assert status 200. Run the runner from IntelliJ. The test should go green. - Add
-Dkarate.env=stagingto the IntelliJ run configuration. Inkarate-config.js, add a branch that sets a differentbaseUrlwhenenv == 'staging'. Confirm the variable switches correctly by printing it:* print baseUrlas the first step in your scenario. - Stretch: install the Karate IntelliJ plugin. Open
users.featureand use the play button next to an individual scenario. Notice that you can run one scenario without running the whole feature — useful when debugging a single failing test.
Next lesson: writing your first feature file — the full set of built-in keywords, the Background block, and how Karate's step keywords differ from Cucumber's.