In an Allure results directory, what does a `-container.json` file hold, and how does it relate to the `-result.json` files beside it?
answer
- two file suffixes, not one
- fixtures live beside the case
- befores and afters
- children is a list of uuids
- FixtureResult has no uuid
basics
~10 sA -container.json file holds Allure's TestResultContainer: setup in befores, teardown in afters, and a children list naming by uuid the results it wraps. The test bodies themselves live in separate -result.json files.
solid answer
~40 sAllure's writer emits loose JSON into a results directory. A `-result.json` file is one finished test case — a `TestResult` with its own `steps`, `attachments` and `status`. A `-container.json` file is a **scope**: a `TestResultContainer` whose `befores` and `afters` hold `FixtureResult` objects for setup and teardown, and whose `children` is a list of **uuids** — not embedded objects — naming the results (or nested containers) that scope covers. So a fixture is never stored inside the test it prepared; it is stored once, beside it, and the container is what says which cases it applied to. That is why a results directory of `-result.json` files alone still renders test bodies, but shows no setup or teardown at all.
code
json · 34 lines{
"uuid": "6b1f0f1e-6c02-4b4a-a0e6-2b3b3f0f9a11",
"name": "CheckoutTest",
"children": [
"7c2a1b33-1d0f-4d55-9c2e-0f7c5c1a7c10",
"9d4e77aa-58cb-4c1a-8f21-5a6f0c2e44b3"
],
"befores": [
{
"name": "startSession",
"status": "passed",
"stage": "finished",
"steps": [],
"attachments": [],
"parameters": [],
"start": 1717070000000,
"stop": 1717070001200
}
],
"afters": [
{
"name": "closeSession",
"status": "passed",
"stage": "finished",
"steps": [],
"attachments": [],
"parameters": [],
"start": 1717070009000,
"stop": 1717070009400
}
],
"start": 1717070000000,
"stop": 1717070009400
}go deeper
Be able to name the two file suffixes and say what each holds: the case body in a result file, the setup and teardown in a container file that lists its children by uuid.
Explain the field-level mechanics: befores and afters hold FixtureResult objects with the same shape as StepResult, and children is a list of uuid strings rather than embedded objects.
Show you can debug from the raw directory — grep a case uuid to find every container that covered it, and recognise a partial run where results flushed but the enclosing container never closed.
Be ready to argue why fixtures were kept out of the result file at all: shared scopes, nesting, and independently written files that stay readable when a run is cut short.
## What the writer puts in a results directory Allure's writer side (`allure-java`) does not build a report. It drops **loose JSON files** into a results directory — `allure-results` by default, overridable through the `allure.results.directory` property — and a separate generator step reads them afterwards. Three file suffixes matter for the step tree: - **`-result.json`** — one finished test case, serialised from `TestResult`. - **`-container.json`** — one *scope*, serialised from `TestResultContainer`. - **`-attachment`** plus the file's own extension — raw bytes referenced by name from a node. Every file is named by a uuid, so nothing in the directory depends on write order and parallel workers can emit into it independently. ## The container: two fixture lists and a list of children `TestResultContainer` carries `uuid`, `name`, `children`, `description`, `descriptionHtml`, `befores`, `afters`, `links`, `start` and `stop`. Two of those fields do the real work: - **`befores`** and **`afters`** are lists of `FixtureResult` — the setup that ran on entry to the scope and the teardown that ran on exit. The writer distinguishes the two directions with a fixture type whose values are `BEFORE` and `AFTER`. - **`children`** is a list of **strings**, not of objects. Each string is the uuid of something else in the same directory: a `-result.json` file, or another `-container.json` file. That second point is the whole design. A container does not contain its children; it **names** them. Containers can therefore nest — a class-scoped container's `children` may list method-scoped containers, which in turn list results. | | `-result.json` (`TestResult`) | `-container.json` (`TestResultContainer`) | |---|---|---| | what it is | one executed test case | one scope around zero or more cases | | body | `steps`, `attachments`, `parameters` | none of its own | | fixtures | none | `befores`, `afters` | | identity | `uuid`, `historyId`, `testCaseId`, `labels`, `links` | `uuid` and `name` only | | membership | implicit, via labels | explicit, via `children` uuids | ## What a `FixtureResult` is — and what it is not A `FixtureResult` has `name`, `status`, `statusDetails`, `stage`, `description`, `descriptionHtml`, `steps`, `attachments`, `parameters`, `start` and `stop`. That is the **same field set as `StepResult`**: both are executable items, so a fixture can carry its own nested steps and its own attachments, exactly as a test body can. Its `status` is one of `FAILED`, `BROKEN`, `PASSED`, `SKIPPED`; its `stage` is one of `SCHEDULED`, `RUNNING`, `FINISHED`, `PENDING`, `INTERRUPTED`. What it does **not** have is just as important: - no `uuid` of its own, - no `historyId` and no `testCaseId`, - no `labels`. A fixture has no independent identity in this model. It exists only as an element of some container's `befores` or `afters`, and it is reachable only through that container. Nothing in the format lets you trend one fixture across runs the way you can trend a case. ## Why the split exists 1. **A fixture is shared.** One class-scoped setup serves many cases. Storing it once and naming the covered cases by uuid avoids writing the same object into every result file. 2. **Scopes nest.** Suite, class and method scopes stack, and a flat list of results has nowhere to put that stacking. `children` gives it a place. 3. **The files are written at different moments.** A result is written when the case finishes; a container is written when its scope closes — after the children it names. The directory is therefore correct at every intermediate point, which is what lets a killed run still produce a readable partial report. ## Reading a results directory by hand When a report looks wrong, the directory is the ground truth: - **Bodies but no setup shown?** Look for `-container.json` files. If the run was killed before the outer scope closed, the results were flushed and the container never was. - **Which fixture applied to this case?** Take the case's `uuid` from its `-result.json` and grep the directory for it; every container whose `children` list contains it contributed its `befores` and `afters`. - **A fixture that seems to have run many times?** Check whether it is one entry in one container that names many children, rather than many entries. The short version: the result file answers *what the test did*; the container file answers *what was done around it, and to whom*.
- Can one `-container.json` name another `-container.json` in its `children`?Yes. `children` is a list of uuid strings and nothing constrains them to results, so a class-scoped container can name method-scoped containers, which in turn name the results. That is how nested scopes are represented in a flat directory of files.
- If a fixture has no `uuid` of its own, how would you follow one fixture across several runs?You cannot do it through the format. A `FixtureResult` carries only `name`, timing, `status` and its own steps and attachments — no identity key, no labels. Any cross-run view of a fixture has to be reconstructed outside the report, by matching on the container name and the fixture name.
Think of a shipping manifest. The boxes (the -result.json files) travel as separate parcels; the manifest (the -container.json) lists the box IDs in this shipment and records the paperwork done before dispatch and after arrival.
saying these in an interview costs you the question
- Says fixtures are stored inside the test result file
- Thinks children embeds the full child results
- Calls a container just another test case
- Assumes one container file per test method always
- Believes a fixture has its own historyId