Q19 of 40 · Karate
How do you structure a Karate project (folders, naming, configuration files)?
KarateMidkarateproject-structureorganisationkarate-configbest-practices
Short answer
Short answer: Place the JUnit runner in src/test/java. Under src/test/resources: karate-config.js at root for environment config, feature files grouped by service domain, helpers/ for reusable features, mocks/ for stub definitions, and data/ for JSON test fixtures. The runner discovers all .feature files under the specified classpath.
Detail
Standard Karate project layout:
src/
test/
java/
com/example/
SuiteRunner.java ← JUnit 5 parallel runner
resources/
karate-config.js ← environment variables, base URL, auth
logback-test.xml ← logging config for test run
features/
users/
create-user.feature
get-user.feature
update-user.feature
orders/
checkout.feature
order-status.feature
helpers/
login.feature ← reusable: called with callonce
create-user.feature ← reusable: test data setup
get-token.feature
utils.js ← JavaScript utilities
mocks/
payment-gateway.feature ← Karate Mock stub definitions
email-service.feature
data/
users/
valid-users.json ← test fixture data
invalid-emails.json
Naming conventions:
- Feature files: kebab-case matching the operation (
create-user.feature) - Helper features: verb-noun (
get-token.feature,create-product.feature) - Runner class:
*Runner.javasuffix for surefire include pattern
karate-config.js: evaluated before every feature. Returns an object whose properties become available as variables in all scenarios. Environment-specific config is the primary use case.
// EXAMPLE
karate-config.js
function fn() {
// Determine target environment from system property
var env = karate.env || 'dev';
karate.log('karate.env =', env);
var config = {
env: env,
baseUrl: 'http://localhost:8080', // default
adminToken: 'dev-static-token'
};
if (env === 'staging') {
config.baseUrl = 'https://staging.api.example.com';
// Fetch dynamic token for staging
var auth = karate.call('classpath:helpers/get-token.feature');
config.adminToken = auth.accessToken;
}
if (env === 'prod') {
config.baseUrl = 'https://api.example.com';
var auth = karate.call('classpath:helpers/get-token.feature');
config.adminToken = auth.accessToken;
karate.configure('ssl', true); // might need relaxed SSL on some envs
}
// Increase timeout for slow environments
karate.configure('connectTimeout', 10000);
karate.configure('readTimeout', 10000);
return config;
}// WHAT INTERVIEWERS LOOK FOR
Domain-based folder organisation (not test-type-based), the helpers/ and mocks/ separation, karate-config.js location and purpose, and the surefire runner naming convention. This structure is standard in real Karate projects.
// COMMON PITFALL
Putting all feature files in a flat directory — this is unmanageable at 50+ features. Domain-based subfolders and a helpers/ separation are essential from the start.