# TestFly Part 9: In-Process Load Testing in Java with Gatling & K6

URL: https://hakangul.lovable.app/blog/testfly-part-9-k6-gatling-load-testing-in-java
Author: Hakan Gül — Team Lead Senior Test Automation Engineer
Published: 2026-09-10
Updated: 2026-09-10
Category: test-automation
Tags: TestFly, Load Testing, Gatling, K6, Performance Testing, Java, SDET

> Learn how TestFly 1.1.0 unifies functional UI/API testing and Gatling/K6 performance testing in a single Java test class with automated P95 SLO assertions.

## English

**TL;DR:** TestFly 1.1.0 introduces built-in load and performance testing capabilities powered by Gatling and lightweight virtual threads. SDETs can now author, parameterize, and execute high-concurrency load scenarios directly inside their standard TestNG or JUnit 5 test classes without context switching or launching external tools.

---

## Why Should Functional and Load Testing Live Together?

In traditional software development life cycles, performance testing is treated as an afterthought or isolated into distinct toolchains (like JMeter GUI or standalone scripts). This separation creates friction:
- Test data and authentication setups are duplicated between functional and performance repos.
- Performance tests are run infrequently, often right before production releases.
- CI/CD quality gates become complex to configure across disparate runners.

TestFly breaks down this wall by allowing engineers to declare load simulations using the same test classes, base configurations (`testfly.yml`), and assertions they already use for WebUI and API automation.

---

## How Does TestFly Load Testing Work?

TestFly provides two complementary authoring styles:

### 1. Declarative Mode with `@LoadTest`

Decorate any test method with `@LoadTest` to schedule concurrent virtual users and ramp-up phases:

```java
package io.testfly.examples.loadtest;

import io.testfly.loadtest.LoadTest;
import io.testfly.test.BaseTest;
import org.testng.annotations.Test;

public class SimpleLoadTest extends BaseTest {

    @Test
    @LoadTest(users = 100, rampUpSeconds = 15, durationSeconds = 60)
    public void testCheckoutUnderSurgeTraffic() {
        apiClient().post("/api/checkout")
            .body("{\"cartId\": 1024}")
            .send()
            .assertStatus(200);
    }
}
```

### 2. Fluent Programmatic DSL with `load()`

For multi-step user journeys and dynamic feeders, use the fluent `LoadScenario` DSL:

```java
package io.testfly.examples.loadtest;

import io.testfly.loadtest.LoadScenario;
import io.testfly.loadtest.LoadTestFeeder;
import io.testfly.test.BaseTest;
import org.testng.annotations.Test;

public class AdvancedLoadJourneyTest extends BaseTest {

    @Test
    public void simulateUserBrowsingJourney() {
        LoadTestFeeder users = LoadTestFeeder.csv("testdata/users.csv");

        LoadScenario.scenario("Search and Add to Cart")
            .feed(users)
            .step("Browse Catalog", client -> client.get("/products?q=shoes").send().assertStatus(200))
            .pause(1000)
            .step("Add to Cart", client -> client.post("/cart/items").body("{\"id\": 42}").send().assertStatus(201))
            .users(500)
            .rampUp(20)
            .run();
    }
}
```

---

## How Does TestFly Enforce Performance SLO Quality Gates?

Raw metrics are meaningless without automated validation. TestFly captures millisecond-precise timings for every request and computes standard percentiles (P50, P90, P95, P99):

| Percentile Metric | Meaning | Typical SLO Target |
|:---|:---|:---|
| **P50 (Median)** | 50% of requests completed faster than this time | < 150 ms |
| **P90** | 90% of requests completed faster than this time | < 350 ms |
| **P95** | 95% of requests completed faster than this time | < 500 ms |
| **P99** | Tail latency affecting 1% of users | < 1200 ms |

Assert your service-level objectives in code to fail the build automatically on performance regressions:

```java
import static io.testfly.loadtest.LoadTestAssert.*;

assertP95Below(Duration.ofMillis(450));
assertErrorRateBelow(0.01); // Less than 1% failures
```

---

## How Are Load Test Results Reported?

TestFly generates an interactive HTML performance report featuring:
- Live latency distribution curves and percentile breakdowns.
- HTTP status code distributions (2xx, 4xx, 5xx).
- Direct export to Allure Reports and ReportPortal for unified enterprise dashboards.

---

## FAQ

### Does TestFly require JMeter or an external binary?
No. TestFly executes simulations in-process using Gatling's high-performance engine or native Java virtual threads, requiring zero external runtime binaries.

### Can I run load tests in CI/CD without overwhelming local machines?
Yes. TestFly load tests run headlessly in CI (GitHub Actions, Bitbucket, Jenkins). For enterprise surges (100k+ RPS), containerized runner pods can be scheduled on Kubernetes.

### Can I mix API authentication tokens with load tests?
Yes. TestFly's `ApiClient` seamlessly passes Bearer tokens and session headers to load testing steps.

## Türkçe

**Özet:** TestFly 1.1.0 sürümü, Gatling ve Java sanal iş parçacıkları (virtual threads) ile güçlendirilmiş dahili yük ve performans testi yeteneklerini sunar. SDET'ler artık harici araçlara ihtiyaç duymadan doğrudan standart TestNG veya JUnit 5 test sınıfları içerisinde yüksek eşzamanlı yük senaryoları yazabilir, parametrelendirebilir ve doğrulayabilir.

---

## Fonksiyonel Testler ile Yük Testleri Neden Aynı Çatıda Olmalı?

Geleneksel yazılım geliştirme süreçlerinde performans testleri hep son aşamaya bırakılır ya da JMeter gibi ayrı kullanıcı arayüzlü araçlara hapsedilir. Bu ayrım şu sorunları doğurur:
- Fonksiyonel testlerde kullanılan test verileri ve auth mekanizmaları yük testleri için sıfırdan tekrar yazılır.
- Performans testleri sadece canlıya çıkış öncesi nadiren koşulur (Shift-Left ilkesine aykırıdır).
- CI/CD hatlarında farklı araçların çıktılarını birleştirmek ve kalite kapıları kurmak zorlaşır.

TestFly bu engeli ortadan kaldırarak mühendislerin aynı `BaseTest` altyapısı, `testfly.yml` ayarları ve assertion kütüphanesiyle yük testleri yazmasını sağlar.

---

## TestFly ile Yük Testi Nasıl Yazılır?

TestFly iki farklı yazım yaklaşımı sunar:

### 1. `@LoadTest` ile Deklaratif Yaklaşım

Herhangi bir test metodunu `@LoadTest` anotasyonu ile işaretleyerek eşzamanlı sanal kullanıcıları ve artış (ramp-up) sürelerini belirleyin:

```java
package io.testfly.examples.loadtest;

import io.testfly.loadtest.LoadTest;
import io.testfly.test.BaseTest;
import org.testng.annotations.Test;

public class BasitYukTesti extends BaseTest {

    @Test
    @LoadTest(users = 100, rampUpSeconds = 15, durationSeconds = 60)
    public void yukAltindaOdemeHizmetiTesti() {
        apiClient().post("/api/checkout")
            .body("{\"cartId\": 1024}")
            .send()
            .assertStatus(200);
    }
}
```

### 2. `LoadScenario` ile Akıcı (Fluent) DSL Yaklaşımı

Çok adımlı kullanıcı gezintilerini ve dinamik veri besleyicilerini (feeder) kodlamak için akıcı DSL kullanılır:

```java
package io.testfly.examples.loadtest;

import io.testfly.loadtest.LoadScenario;
import io.testfly.loadtest.LoadTestFeeder;
import io.testfly.test.BaseTest;
import org.testng.annotations.Test;

public class GelismisGezintiTesti extends BaseTest {

    @Test
    public void kullaniciAlisverisGezintisi() {
        LoadTestFeeder kullanicilar = LoadTestFeeder.csv("testdata/users.csv");

        LoadScenario.scenario("Katalog Arama ve Sepete Ekleme")
            .feed(kullanicilar)
            .step("Katalog Arama", client -> client.get("/products?q=ayakkabi").send().assertStatus(200))
            .pause(1000)
            .step("Sepete Ekle", client -> client.post("/cart/items").body("{\"id\": 42}").send().assertStatus(201))
            .users(500)
            .rampUp(20)
            .run();
    }
}
```

---

## Performans Kalite Kapıları (SLO) Nasıl Denetlenir?

Ölçümlenen veriler otomatik olarak P50, P90, P95 ve P99 yüzdeliklerine dönüştürülür:

| Yüzdelik (Percentile) | Anlamı | Tipik Hedef (SLO) |
|:---|:---|:---|
| **P50 (Medyan)** | İsteklerin %50'sinin tamamlanma süresi | < 150 ms |
| **P90** | İsteklerin %90'ının tamamlanma süresi | < 350 ms |
| **P95** | İsteklerin %95'inin tamamlanma süresi | < 500 ms |
| **P99** | En yavaş %1'lik kuyruk gecikmesi | < 1200 ms |

Sözleşmelerinizi kod üzerinden doğrulayarak performans gerilemelerinde (regression) CI derlemesini otomatik kırabilirsiniz:

```java
import static io.testfly.loadtest.LoadTestAssert.*;

assertP95Below(Duration.ofMillis(450));
assertErrorRateBelow(0.01); // %1'den az hata oranı
```

---

## SSS

### TestFly yük testi için JMeter veya harici bir kuruluma ihtiyaç duyar mı?
Hayır. TestFly, Gatling motorunu ve Java sanal iş parçacıklarını dahili olarak çalıştırır; harici hiçbir binary kurulumu gerekmez.

### TestFly yük testleri CI/CD pipeline'ında çalıştırılabilir mi?
Evet. GitHub Actions, Jenkins ve Bitbucket Pipelines üzerinde headless olarak çalışır. Yüksek hacimli yükler için Docker ve Kubernetes podları ile yatayda ölçeklenebilir.

### API yetkilendirme (Bearer token) yük testlerine dahil edilebilir mi?
Evet. `ApiClient` üzerinden alınan token veya oturum çerezleri yük testi senaryosundaki tüm adımlara otomatik enjekte edilir.
