Skip to main content

CORE SYNTAX

Project Structure

Organize your Karate project for maintainability and team collaboration using proven folder structures, naming conventions, and build configurations.

Maven Project Layout

my-karate-project/
├── pom.xml # Maven configuration
├── src/test/java/ # All test files (recommended)
│ ├── karate-config.js # Global configuration
│ ├── logback-test.xml # Logging configuration
│ ├── TestRunner.java # Main test suite runner
│ │
│ ├── users/ # Domain-specific tests
│ │ ├── users.feature # Feature tests
│ │ ├── user-data.json # Test data
│ │ └── UsersRunner.java # Individual runner
│ ├── products/
│ │ ├── products.feature
│ │ └── product-data.csv
│ │
│ ├── auth/ # Reusable components
│ │ ├── login.feature
│ │ └── oauth-flow.feature
│ │
│ └── common/ # Shared utilities
│ ├── api-helpers.feature
│ ├── validators.js
│ └── test-data.json

└── target/ # Generated files
├── karate-reports/ # HTML test reports
└── surefire-reports/ # JUnit XML reports

Key Design Principles

  • Co-location: Keep tests and test data together
  • Domain organization: Group by business functionality
  • Shared resources: Common utilities accessible via classpath:
  • Standard conventions: Follow Maven/Gradle patterns

Configuration Files

Global Configuration (karate-config.js)

Must be placed in the classpath root (src/test/java/):

function fn() {
var env = karate.env || 'dev';

var config = {
baseUrl: 'https://api.dev.example.com',
authUrl: 'https://auth.dev.example.com',
timeout: 30000
};

// Environment-specific overrides
if (env == 'staging') {
config.baseUrl = 'https://api.staging.example.com';
} else if (env == 'prod') {
config.baseUrl = 'https://api.example.com';
config.timeout = 60000;
}

return config;
}

Logging Configuration (logback-test.xml)

Place in src/test/java/ for proper classpath access:

logback-test.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level - %msg%n</pattern>
</encoder>
</appender>

<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>target/karate.log</file>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level - %msg%n</pattern>
</encoder>
</appender>

<logger name="com.intuit.karate" level="DEBUG"/>

<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="FILE"/>
</root>
</configuration>

Build Configuration

Maven Setup

Configure Maven to work optimally with Karate:

pom.xml
<build>
<!-- Co-locate resources with Java files -->
<testResources>
<testResource>
<directory>src/test/java</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</testResource>
</testResources>

<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M9</version>
<configuration>
<includes>
<include>**/*Test.java</include>
</includes>
</configuration>
</plugin>
</plugins>
</build>

Gradle Setup

build.gradle
sourceSets {
test {
resources {
srcDir file('src/test/java')
exclude '**/*.java'
}
}
}

test {
useJUnitPlatform()
systemProperty "karate.options", System.properties.getProperty("karate.options")
systemProperty "karate.env", System.properties.getProperty("karate.env")
outputs.upToDateWhen { false }
}

Naming Conventions

File Naming Best Practices

File TypeConventionExample
Feature fileskebab-case.featureuser-authentication.feature
Test runnersPascalCaseRunner.javaUsersRunner.java
Test suitesPascalCaseTest.javaApiTestSuite.java
Data filesdescriptive-name.jsonvalid-user-data.json
UtilitiescamelCase.jsauthHelpers.js

Strategic Test Organization

// Example test runners
class ApiTestSuite { // Runs ALL tests via "mvn test"
@Test
void testParallel() {
Runner.path("classpath:").tags("~@ignore").parallel(5);
}
}

class UsersRunner { // Development runner (IDE only)
@Karate.Test
Karate userTests() {
return Karate.run("users").relativeTo(getClass());
}
}

Resource Loading

Classpath vs Relative Paths

Feature: Resource loading strategies

Scenario: Different path types # Classpath root access (recommended for shared resources)

* def commonAuth = read('classpath:auth/login.feature')
* def sharedData = read('classpath:common/data.json')

# Relative access (for feature-local resources)
* def localData = read('user-data.json')
* def schema = read('user-schema.json')

# This feature prefix (for called features)
* def helper = read('this:helper.feature')

Understanding Classpath

The classpath includes:

  1. src/test/java/ - With Maven/Gradle resource configuration
  2. src/test/resources/ - Standard Maven/Gradle location
  3. External JARs - Dependencies and shared libraries

Next Steps

Master project organization and continue with: