skip to content

In a CI job that runs an Allure-instrumented suite, what does the `allure.results.directory` property control, and why must the step that uploads the run point at the same directory?

level: juniorimportance: must knowfreq 60%

answer

  1. a local path, not a server
  2. the adaptor writes files, not requests
  3. two steps name the same directory
  4. defaults to allure-results
  5. empty push, no error

basics

~20 s

allure.results.directory names the local folder the Allure adaptor writes its per-test result files into during the run; it defaults to allure-results. The upload step is a plain directory copy, so if it reads a different path it pushes nothing.

solid answer

~40 s

An Allure adaptor never talks to a results store while the suite runs. It serialises each finished test to a file on the runner's local disk, in a directory that defaults to `allure-results` and is moved by setting `allure.results.directory`. The publish step at the end of the job is then an ordinary directory operation — archive that path and push it. Nothing links the two: the path is named once by the test invocation and again by the upload step. When they disagree, the upload succeeds against an empty or stale directory and the store records a run with no tests, with no error anywhere. The fix is to name the directory once, as a job-level variable, as an absolute path, and have both steps reference it.

code

bash · 4 lines
bash
RESULTS_DIR="$PWD/target/allure-results"
mvn test -Dallure.results.directory="$RESULTS_DIR"
tar -czf allure-results.tgz -C "$RESULTS_DIR" .
curl -fsS -X POST --data-binary @allure-results.tgz "$RESULTS_STORE_URL"

go deeper

for a junior

Know that the property points at a local folder on the runner, that it defaults to allure-results, and that the upload step reads that same folder.

for a middle

Explain that results are written file-per-test in-process, so the path is named twice — once by the test run and once by the push — and nothing checks that the two agree.

for a senior

Show how you would stop a silent empty or stale upload: one absolute job variable feeding both steps, plus a non-empty assertion immediately before the push.

for a principal

Argue for owning this plumbing centrally — a shared publish step every team calls — rather than letting each pipeline re-invent the path handoff and rediscover the same silent failure.

## What the property actually controls `allure.results.directory` is a **writer-side** setting. The Allure adaptor running inside your test process does not open a connection to a results server; it writes files. As each test finishes, the adaptor serialises it and drops the file into one directory on the machine executing the tests. That directory defaults to `allure-results`, resolved against the working directory of the process running the tests. Setting `allure.results.directory` moves it somewhere else — typically under the build tool's output directory, so a clean build removes it. Two properties of that sentence matter to whoever writes the delivery step: - It is read by the **test process**, not by the build tool wrapper and not by the CI agent. If your build forks a JVM for tests, the value has to actually reach the forked process, or the fork writes to its own default. - It is a **path, not a URL**. Nothing about this property names a store, a project, or a credential. It only says where on local disk the bytes land. ## What is in the directory when the suite ends A finished results directory is a flat pile of files, not a report: - one `-result.json` per test that finished - `-container.json` files describing the fixtures wrapped around them - `-attachment` files holding the raw bytes of anything a test attached - whole-run files the **job** contributes rather than the tests: `executor.json`, `environment.properties`, `categories.json` The important structural fact for delivery is that the per-test files are written **incrementally, one per test, as each test finishes**. The directory is therefore always a valid directory — just, until the process exits, an incomplete one. ## Why the upload has to agree on the path The publish step is a directory operation: archive a path and send it, or hand the path to a client that walks it. That means the path is named in **two independent places** — once on the command that runs the tests, once on the step that pushes — and nothing in the tooling checks that they match. The failure is quiet in both directions: 1. **Upload reads a path the run never wrote to.** The archive is empty. The push succeeds. The store shows a run with zero tests, or refuses it with a message about an empty payload that reads like a transient problem. 2. **Upload reads a stale path.** On a runner with a cached or reused workspace, an old `allure-results` from a previous build may still be sitting there. The push succeeds and the store records last week's run under this build's identity — worse than nothing, because it looks right. ## Three directories people confuse | Thing | What it is | Default | |---|---|---| | `allure.results.directory` | where the adaptor **writes** raw results during the run | `allure-results` | | the report output directory | where a generator **writes HTML** afterwards | `allure-report` | | the test plan | which tests the run **selects**, via `testplan.json` / `ALLURE_TESTPLAN_PATH` | none | Only the first is what the upload reads. Pointing the publish step at the report directory pushes a generated site instead of results; pointing it at the test plan pushes a selection file. ## Making it hard to get wrong - **Name the directory once.** A single job-level variable, referenced by the test invocation and by the upload. Two literals in two steps will drift the first time somebody edits one of them. - **Use an absolute path.** A relative path is resolved against the working directory of whichever process reads it, and the test process's working directory is not reliably the job's checkout root once forking is involved. - **Assert before you push.** One check that the directory exists and is non-empty, run immediately before the upload, converts a silent empty push into a red step. It is the cheapest guard on this whole path. None of this needs the Allure command-line tool on the runner. The results directory is plain JSON plus attachment bytes written in-process by the adaptor; turning it into something a person reads happens later, and a results server does that itself.

  • The team sets the property to a relative path and the upload sometimes finds nothing. What is going on?
    A relative path is resolved against the working directory of whichever process reads it. The build tool's working directory is the checkout root, but a forked test JVM may not share it, so the adaptor writes somewhere the upload never looks. Deriving one absolute path from a job variable removes the ambiguity entirely.
  • Does the runner need the Allure command-line tool installed for the upload to work?
    No. The results directory is written in-process by the adaptor and is just JSON files plus attachment bytes, so archiving and pushing it needs nothing Allure-specific. The command-line tool is only needed to turn a results directory into something a person can read, and a results server does that on its own side.

saying these in an interview costs you the question

  • Thinks the property names the results server
  • Confuses the results directory with the generated report directory
  • Assumes the upload step discovers the directory automatically
  • Believes an empty results directory makes the push fail loudly