Chuyển đến nội dung chính

Lesson 5: Gatling and Artillery — Comparison and Practice

Gatling Scala/Java DSL, Artillery YAML-based testing. Compare k6 vs Gatling vs Artillery for each use case.

🔒 DevSecOps — Lesson 5 Lesson 5: Gatling and Artillery — Compare and Practice__HTMLTAG_55___

Performance Testing & Pentest: Enterprise Standard Process 2026

Part 1: Performance Testing Platform

xdev.asia

1. Gatling — Java/Scala DSL

# Cài đặt
# Option 1: Gatling bundle
wget https://repo1.maven.org/maven2/io/gatling/highcharts/gatling-charts-highcharts-bundle/3.11.5/gatling-charts-highcharts-bundle-3.11.5.zip

# Option 2: Maven plugin
mvn gatling:test

# Option 3: Gradle plugin
gradle gatlingRun

Gatling Simulation (Java DSL)

// src/test/java/simulations/ProductLoadTest.java
import io.gatling.javaapi.core.*;
import io.gatling.javaapi.http.*;
import static io.gatling.javaapi.core.CoreDsl.*;
import static io.gatling.javaapi.http.HttpDsl.*;

public class ProductLoadTest extends Simulation {

  HttpProtocolBuilder httpProtocol = http
    .baseUrl("https://api.example.com")
    .acceptHeader("application/json")
    .contentTypeHeader("application/json")
    .userAgentHeader("Gatling/LoadTest");

  // Feeder: test data
  FeederBuilder<String> userFeeder = csv("users.csv").random();

  ScenarioBuilder browseProducts = scenario("Browse Products")
    .feed(userFeeder)
    .exec(
      http("Login")
        .post("/api/auth/login")
        .body(StringBody("{\"email\":\"#{email}\",\"password\":\"#{password}\"}"))
        .check(jsonPath("$.accessToken").saveAs("token"))
    )
    .pause(1, 3)
    .exec(
      http("List Products")
        .get("/api/products?page=1&limit=20")
        .header("Authorization", "Bearer #{token}")
        .check(
          status().is(200),
          jsonPath("$.data[*].id").findAll().saveAs("productIds"),
          responseTimeInMillis().lt(300)
        )
    )
    .pause(2, 5)
    .exec(
      http("Product Detail")
        .get("/api/products/#{productIds.random()}")
        .header("Authorization", "Bearer #{token}")
        .check(status().is(200))
    );

  {
    setUp(
      browseProducts.injectOpen(
        rampUsers(100).during(120),     // Ramp to 100 users in 2 min
        constantUsersPerSec(50).during(300), // 50 users/sec for 5 min
        rampUsers(500).during(120)      // Ramp to 500 users in 2 min
      )
    ).protocols(httpProtocol)
     .assertions(
       global().responseTime().percentile3().lt(500),  // p95 < 500ms
       global().responseTime().percentile4().lt(2000), // p99 < 2s
       global().failedRequests().percent().lt(1.0)     // < 1% failures
     );
  }
}

Gatling Report

Gatling tự động generate HTML report với:
  ├── Response time distribution (histogram)
  ├── Response time percentiles over time
  ├── Requests per second chart
  ├── Active users over time
  ├── Response time vs request/sec
  └── Assertions results (pass/fail)

Output: target/gatling/productloadtest-{timestamp}/index.html

2. Artillery — YAML-based Testing

# Cài đặt
npm install -g artillery
artillery --version

# Chạy test
artillery run test.yml
artillery run --output report.json test.yml
artillery report report.json  # Generate HTML report

Artillery Test Definition__HTMLTAG_80___
# tests/load/artillery-test.yml
config:
  target: "https://api.example.com"
  phases:
    - duration: 120      # 2 min ramp up
      arrivalRate: 5
      rampTo: 50
      name: "Warm up"
    - duration: 300      # 5 min sustain
      arrivalRate: 50
      name: "Sustained load"
    - duration: 120      # 2 min spike
      arrivalRate: 200
      name: "Spike"

  defaults:
    headers:
      Content-Type: "application/json"

  plugins:
    expect: {}
    metrics-by-endpoint: {}

  ensure:
    thresholds:
      - http.response_time.p95: 300   # p95 < 300ms
      - http.response_time.p99: 1000  # p99 < 1s
      - http.codes.500: 0             # Zero 500 errors

  payload:
    path: "data/users.csv"
    fields:
      - "email"
      - "password"

scenarios:
  - name: "User Journey"
    weight: 70    # 70% traffic
    flow:
      - post:
          url: "/api/auth/login"
          json:
            email: "{{ email }}"
            password: "{{ password }}"
          capture:
            - json: "$.accessToken"
              as: "token"
          expect:
            - statusCode: 200

      - think: 2

      - get:
          url: "/api/products?page=1&limit=20"
          headers:
            Authorization: "Bearer {{ token }}"
          capture:
            - json: "$.data[0].id"
              as: "productId"
          expect:
            - statusCode: 200
            - hasProperty: "data"

      - think: 3

      - get:
          url: "/api/products/{{ productId }}"
          headers:
            Authorization: "Bearer {{ token }}"
          expect:
            - statusCode: 200

  - name: "Search"
    weight: 30    # 30% traffic
    flow:
      - get:
          url: "/api/search?q=laptop&limit=10"
          expect:
            - statusCode: 200

Artillery Plugins

# Plugin: publish metrics to Datadog
config:
  plugins:
    publish-metrics:
      - type: datadog
        apiKey: "{{ $processEnvironment.DD_API_KEY }}"
        prefix: "artillery."
        tags:
          - "env:staging"
          - "test:load"

    # Plugin: CloudWatch
    cloudwatch:
      namespace: "Artillery/LoadTests"

3. Compare k6 vs Gatling vs Artillery

Criteria_k6_GatlingArtillery_
Language languageJavaScriptJava/Scala/KotlinYAML + JS
RuntimeGoJVM (Scala)Node.js
Performance__Very HighHighMedium average
Learning curve_LowMediumVery low
CI/CD integrationExcellent_Good (Maven/Gradle)Good (npm)
Distributedk6 Operator (K8s)EnterpriseArtillery Pro
Browser testingk6 browser module_NoPlaywright plugin
ReportJSON/PrometheusBeautiful HTMLJSON/HTML
Cloud SaaS_Grafana Cloud k6Gatling EnterpriseArtillery Pro
EcosystemGrafana, PrometheusJVM ecosystemNode.js ecosystem
Best forDevOps/SRE teamsJava/EnterpriseQuick API tests

4. When to use which tool?

Chọn k6 khi:
  ✅ Team đã dùng Grafana ecosystem
  ✅ Cần tích hợp CI/CD mạnh
  ✅ Cần distributed testing trên K8s
  ✅ Muốn viết test bằng JavaScript

Chọn Gatling khi:
  ✅ Team Java/Scala/Spring Boot
  ✅ Cần report HTML sẵn đẹp
  ✅ Enterprise environment
  ✅ Complex scenario scripting

Chọn Artillery khi:
  ✅ Team nhỏ, cần MVP nhanh
  ✅ API testing đơn giản
  ✅ Prefer YAML over code
  ✅ Node.js application testing

5. Summary

  • Gatling: Mature, JVM-based, excellent reports, strong enterprise adoption
  • Artillery: YAML-first, lowest learning curve, good for quick API tests
  • k6: Best developer experience, Grafana ecosystem, distributed via K8s
  • There is no "best" tool — choose based on team skills, tech stack, and requirements

The next article will learn API Performance Testing — REST, GraphQL, gRPC, WebSocket.