Q26 of 40 · Karate
How would you architect a Karate framework for a microservices team?
Short answer
Short answer: Organise feature files by service domain under a shared test repository. Use karate-config.js to route baseUrl per service via environment variables. Share authentication and common data-setup features in a helpers/ module. Run each service's feature set in parallel — Karate's runner supports multi-path configuration and tag-based filtering.
Detail
Repository strategy: centralised vs per-service.
Centralised test repo (recommended for small-to-medium teams): one repo with subfolders per service. Easier to share helpers, run cross-service flows, and enforce standards.
Per-service test submodule: each service owns its own Karate tests in a Maven submodule. Better separation of concerns but harder to write cross-service flows.
Typical central structure:
features/
user-service/
order-service/
payment-service/
notification-service/
helpers/
auth/
get-token.feature
data/
create-user.feature
create-order.feature
karate-config.js ← routes per service
karate-config.js for multiple service URLs:
config.userServiceUrl = env === 'staging' ? 'https://users.staging.svc' : 'http://localhost:8081';
config.orderServiceUrl = env === 'staging' ? 'https://orders.staging.svc' : 'http://localhost:8082';
config.paymentServiceUrl = env === 'staging' ? 'https://payments.staging.svc' : 'http://localhost:8083';
Tag-based CI: each service's CI pipeline runs only its tagged tests:
mvn test -Dkarate.env=staging -Dkarate.options="--tags @user-service"
Cross-service flow tests: tag them @integration and run in a nightly suite that requires all services to be up.
// EXAMPLE
SuiteRunner.java
// Run tests for all services in parallel
class FullSuiteRunner {
@Test
void runAllMicroserviceTests() {
Results results = Runner
.path(
"classpath:features/user-service",
"classpath:features/order-service",
"classpath:features/payment-service"
)
.tags("~@wip", "~@manual")
.outputJunitXml(true)
.parallel(8); // 8 threads for ~3 services × 2-3 parallel features each
assertThat(results.getFailCount()).isZero();
}
}
// Run a single service's tests (per-service CI)
class UserServiceRunner {
@Test
void runUserServiceTests() {
Results results = Runner
.path("classpath:features/user-service")
.tags("@user-service", "~@wip")
.parallel(4);
assertThat(results.getFailCount()).isZero();
}
}