Skip to content

Repository files navigation

jallure

GitHub release License Gradle JMeter Allure

A Groovy-based integration that generates Allure Report compatible results directly during Apache JMeter test execution.

⚠️ Not suitable for load testing — designed for functional/API test reporting.


Quick Start

Prerequisites

  • Java 11+
  • Docker & Docker Compose (optional, for containerized runs)

Allure CLI is downloaded automatically by Gradle — no manual installation required.


1. Clone & Build

git clone <repo-url>
cd jallure

# Assemble self-contained groovy scripts from modular classes
./gradlew assembleJallureScripts

After this step you will have:

  • build/assembled-groovy/jallure.groovy — main reporter

2. Local Run

Option A — Non-GUI (headless)

# Step 1: Run the example test plan
./gradlew jmeterRun

# Step 2: Generate and open the Allure report
./gradlew allureServe

Option B — GUI

# Step 1: Launch JMeter with the example test plan
./gradlew jmeterGui

# Step 2: Press the **Start** (▶) button in JMeter to execute the test

# Step 3: After the run, generate and open the Allure report
./gradlew allureServe

The task patches JMX paths automatically and opens JMeter GUI with the example test plan pre-loaded.

Option C — Your own JMX

By default, jmeterRun / jmeterGui use src/test/resources/allure-jmeter-example.jmx.

# Assemble scripts (if you changed source classes)
./gradlew assembleJallureScripts

# Run any JMX file (paths inside it will be auto-patched)
./gradlew jmeterRun -PjmxFile=/path/to/your-test.jmx

# Then view the report as usual
./gradlew allureServe

3. Docker Run

# Step 1: Assemble scripts (Docker copies them from build/assembled-groovy/)
./gradlew assembleJallureScripts

# Step 2: Build image and run container
docker compose -f docker/docker-compose.yml up --build

# Step 3: Generate and open the Allure report from container results
./gradlew allureServe

Results will appear in build/allure-results/.

Note: Files created by Docker are owned by root. To clean them up later, use sudo rm -rf build/allure-results/.


Project Structure

├── build.gradle                        # Gradle build configuration
├── settings.gradle
├── gradlew / gradlew.bat / gradle/wrapper/
├── src/
│   ├── main/groovy/
│   │   └── io/github/forcasic/jmeter/allure/
│   │       ├── JsonUtils.groovy          # JSON escaping & content-type utilities
│   │       ├── JMeterContext.groovy      # JMeter binding wrapper
│   │       ├── AttachmentWriter.groovy   # File I/O for Allure attachments
│   │       ├── AllureResultBuilder.groovy# Allure 2.x JSON builder
│   │       └── AllureReporter.groovy     # Main reporter logic
│   ├── main/resources/jmeter/            # Custom JMeter config
│   └── test/
│       ├── groovy/.../allure/            # Spock unit & integration tests
│       └── resources/
│           ├── allure-jmeter-example.jmx # Example test plan
│           └── expected_results.json     # Reference state for validation
├── build/
│   └── assembled-groovy/               # Auto-generated self-contained scripts
│       └── jallure.groovy
├── docker/
│   ├── Dockerfile                        # Docker image for JMeter + Allure
│   ├── docker-compose.yml                # Docker Compose for local run
│   └── .dockerignore
├── docs/                               # Documentation
│   ├── jallure_usage.md                # Detailed usage instructions
│   ├── test_composition_guide.md       # JMX composition guide
│   └── project_structure.md            # Project structure & troubleshooting
├── README.md
├── NOTICE                              # Attribution notice
└── LICENSE

Important: The canonical source is the modular classes under src/main/groovy/io/github/forcasic/jmeter/allure/. The assembled scripts in build/assembled-groovy/ are auto-generated by ./gradlew assembleJallureScripts.


How It Works

  1. Attach jallure.groovy as a JSR223 Assertion to your JMeter samplers.
  2. Set Allure annotations via JMeter variables (vars.put("allure.name", "...")).
  3. Use parameters: start, continue, stop, or leave empty for solo mode.
  4. The script writes Allure 2.x *-result.json files and attachments in real time.

See docs/jallure_usage.md for detailed usage instructions.


Known Limitation: Orphaned Label Leak

When a multi-step test case does not receive a stop (e.g. the thread crashed or the stop sampler was skipped), its allure.label.* variables remain in JMeter's vars. The next test case may inadvertently inherit them.

Why the reporter cannot fix this automatically: jallure.groovy runs as a JSR223 Assertion (after the HTTP sampler), while annotations are declared in a JSR223 Sampler (before the HTTP sampler). By the time the reporter sees a new start, vars already contains a mix of old leaked labels and new intentional ones — the code cannot tell them apart.

Recommended workaround: Add a one-time init sampler at the start of your ThreadGroup that stores a clearLabels closure, then call it inside any declaration sampler that must start with a clean label state:

// Init sampler (run once per thread)
vars.putObject("allure.clearLabels", { ->
    Set copy = new HashSet(vars.entrySet())
    for (Iterator iter = copy.iterator(); iter.hasNext();) {
        def var = iter.next()
        String key = var.getKey()
        if (key.startsWith("allure.label") || key.startsWith("allure.links") || key.startsWith("allure.label.AS_ID")) {
            vars.remove(key)
        }
    }
})
// Inside "Declare allure annotations" for affected cases
vars.getObject("allure.clearLabels")?.call()
vars.put("allure.name", "My Case")
// ... set remaining labels

Key Features

  • Multi-step test cases with start / continue / stop
  • Automatic request/response attachments
  • Assertion results as sub-steps
  • Support for labels, links, parameters, severity, tags, owner, layer, issues
  • Step-level parameters via parameters=[var1,var2] modifier
  • Feature suffix via allure.feature.suffix variable
  • Sensitive header redaction (Authorization, X-Api-Token)
  • Binary content detection (PDF, images, Office docs, etc.)
  • Critical mode (stop thread on failure)

Build & Development

Gradle Tasks

Task Description
./gradlew test Compile test sources (no unit tests currently)
./gradlew jmeterRun Download JMeter and run example JMX (non-GUI)
./gradlew jmeterRun -PjmxFile=... Run your own JMX file
./gradlew jmeterGui Download JMeter and open GUI with example JMX
./gradlew jmeterGui -PjmxFile=... Open GUI with your own JMX file
./gradlew allureGenerate Generate Allure HTML report
./gradlew allureOpen Open Allure report in browser
./gradlew allureServe Serve Allure report via local web-server
./gradlew validateAllureResults Validate generated Allure results
./gradlew integrationTest Full pipeline: JMeter run + validation
./gradlew cleanAllure Delete generated Allure results and reports

Updating Reference State

After intentional behavioral changes, regenerate src/test/resources/expected_results.json:

./gradlew jmeterRun
# Then run the Python snippet below to regenerate expected_results.json
python3 - <<'PY'
import json, glob, os
results_dir = 'build/allure-results'
tests = []
for fp in sorted(glob.glob(os.path.join(results_dir, '*-result.json'))):
    d = json.load(open(fp))
    test = {
        'name': d.get('name', ''),
        'feature': '',
        'story': '',
        'mode': 'multi' if len(d.get('steps', [])) > 1 else 'solo',
        'main_steps': len(d.get('steps', [])),
        'steps': []
    }
    for l in d.get('labels', []):
        if l['name'] in ('feature', 'story'):
            test[l['name']] = l['value']
    for s in d.get('steps', []):
        test['steps'].append({
            'name_pattern': s.get('name', '').split(':')[0] if ':' in s.get('name', '') else s.get('name', '')[:30],
            'sub_steps': len(s.get('steps', [])),
            'has_attachments': len(s.get('attachments', [])) >= 2
        })
    tests.append(test)
with open('src/test/resources/expected_results.json', 'w') as f:
    json.dump({'_comment': 'Auto-generated', 'total_tests': len(tests), 'expected_tests': tests}, f, indent=2, ensure_ascii=False)
print(f'Updated {len(tests)} tests')
PY

License

Apache License 2.0 — see LICENSE.


Author

Forcasic

About

Groovy-based Allure Report integration for Apache JMeter — generates Allure 2.x results in real-time during test execution

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages