Execution Engines (Gatling vs. JDK)
TestFly is engine-agnostic. It features a dual-engine architecture designed to deliver maximum flexibility: an ultra-high performance Gatling engine for enterprise load simulations, and a zero-dependency JDK engine for lightweight local smoke tests.
1. Engine Comparison
| Feature | Gatling Engine (gatling) | JDK Engine (jdk) |
|---|---|---|
| Underlying Tech | Gatling 3.13.x + Netty async IO | Java 21+ HttpClient + Virtual Threads |
| Classpath Dependency | Optional (gatling-charts-highcharts) | Built into Java standard library |
| Process Isolation | Dedicated forked JVM subprocess | Runs in-process on test worker thread |
| Native Report | Interactive Highcharts HTML report | Integrated TestFly HTML dashboard |
| Subprocess Log | gatling-subprocess.log | Standard TestFly logs |
| Recommended For | Benchmark runs, stress tests, CI pipelines | Local dev smoke tests, fast pull requests |
2. Automatic Engine Selection (auto)
By default, loadtest.engine: auto uses dynamic classpath inspection:
// If io.gatling.app.Gatling is found on the classpath:
// Uses GatlingEngine
// Else:
// Silently falls back to JdkLoadEngine without throwing ClassNotFoundException
This means developer machines without Gatling dependencies can still run the entire test suite without modification.
3. Explicit Engine Selection
Force an engine at the configuration or test level:
In testfly.yml
loadtest:
engine: gatling # or 'jdk'
In Code (Fluent API)
load("/api/health")
.engine("jdk") // Forces JDK engine for fast execution
.users(10)
.run();
Via Annotation
@Test
@io.testfly.loadtest.LoadTest(engine = "gatling")
public void stressTest() {
load("/api/payment/checkout").run();
}
Concurrency and throughput depend on hardware, the target service and scenario. No fixed capacity or startup time is guaranteed; measure your workload. JDK load execution uses its own transport, so ApiClient interceptors and mock rules do not automatically apply.