An Allure report shows every case of a parameterised suite with a single history point on every build, and one of the recorded parameters carries a value that differs each run. How does that produce the symptom, and how would you fix it?
answer
- the series never gets past one point
- every parameter is identity by default
- look for a value the CI injects
- check case identity before blaming a rename
- there is a flag that keeps it out
basics
~20 sA per-run parameter value feeds the history key, so every build produces a fresh historyId and a series one point long. Fix it by flagging that parameter as excluded from the key, or by assigning historyId yourself.
solid answer
~50 s`historyId` is derived from `testCaseId` plus the parameter name and value pairs the run recorded, and every parameter is part of the key by default. A parameter carrying a timestamp, a build number, a worker index or a generated identifier therefore mints a new key on every build, and a new key is a new series - which is why each case shows exactly one point and the count of distinct series grows by the size of the suite each run. Confirm it by comparing one test's `testCaseId` across two runs first: if that is unchanged, no rename happened and the culprit is in the `parameters` array. The fixes, in order: stop recording the value as a parameter if it is run context rather than identity; flag it as excluded from the key so it still displays without forking the series; or assign `historyId` explicitly.
code
json · 9 lines{
"historyId": "e7a03c95b1d84f2670ac3e19d5b8f042",
"testCaseId": "3f1b9c0d4a7e2b615c8d0f39a24e7b81",
"fullName": "io.qameta.allure.CartTest.appliesDiscount",
"parameters": [
{ "name": "tier", "value": "GOLD" },
{ "name": "runId", "value": "2026-09-08T11:42:07Z" }
]
}go deeper
Recall that anything recorded as a parameter becomes part of the key, so a value that changes each run gives the test a different key each run.
Name the values that leak in - timestamps, build numbers, shard indexes, generated ids - and explain why each one forks the series rather than just cluttering the report.
Diagnose it against a rename by checking case identity first, then choose between dropping the parameter, excluding it from the key, and assigning the key explicitly.
Set the rule your teams apply for what a parameter is allowed to carry, and accept that it is an identity contract every suite in the estate then inherits.
## The mechanism behind the symptom `historyId` is derived from `testCaseId` plus the parameter name and value pairs the run recorded. Every parameter is, by default, part of the key. So a parameter whose value differs on every build produces a different key on every build, and a different key is a different series. The result is a report in which nothing is wrong and nothing accumulates: - every case shows a trend exactly one point long; - the number of distinct series grows by the size of the suite on every build; - anything the report computes by comparing this outcome against the stored series has no stored series to compare against; - no error, no warning -- each result genuinely is the first of its kind. ## The usual culprits These are the values that end up in `parameters` without anyone intending them to be identity: - a **timestamp** or an ISO date-time captured at run start; - a **run, build or pipeline number** injected from the CI environment; - a **worker, shard or thread index** from a parallel runner, which also makes the key depend on scheduling; - a **host name** or container id from an ephemeral runner; - a **randomised fixture value** -- a generated e-mail address, a UUID for a created record, a seeded random input; - a **temporary directory or file path** created per run. The shard index deserves a special mention because it produces an intermittent version of the same fault: the series survives as long as a test lands on the same worker, and forks the moment the runner reschedules it. ## Confirming it in one minute 1. Take one test's `*-result.json` from two consecutive runs. 2. Compare `testCaseId` across the two. If it is the same, the code did not move and a rename is not the cause. 3. Compare the `parameters` arrays. Any pair whose value differs between the two runs is the one splitting the series. That ordering matters: checking `testCaseId` first separates this fault from a refactor, which shows the same symptom from a different cause and needs a different fix. ## Three fixes, in order of preference | fix | trend restored? | value still visible? | when to choose it | |---|---|---|---| | stop recording it as a parameter | yes | no -- move it to a label, an attachment or the description | the value is diagnostic context, not part of what the test does | | flag the parameter as excluded from the key | yes | yes | a reader genuinely needs the value on the result | | assign `historyId` explicitly | yes | yes | identity should come from somewhere outside the code entirely | **Removing the parameter** is the cleanest when the value was never part of the test's identity. A build number belongs with the run, not with the case, and a report has other places to put run-level context. **Excluding it from the key** is the option most people want and most people miss. The writer skips flagged parameters when it builds the source string, so the value still renders on the result while the series stays intact. This is the intended answer for a value a human needs to see -- the host the row ran on, say -- that must not fork identity. **Assigning `historyId`** is the heaviest option, and it is right when the whole identity scheme should be external rather than derived. ## The mirror-image mistake Over-splitting is the common failure, but the opposite exists and is worth naming, because the fix for one causes the other. Exclude too much and two genuinely different data rows collapse onto the same key: their outcomes interleave in one series, and a stable green row and a stable red row together look exactly like one unstable test. The test for whether a parameter belongs in the key is simple and it is not about volatility -- **does changing this value change what the test asserts?** If yes, it is identity and it stays in. If it only changes where or when the test ran, it is context and it comes out.
- What is the opposite failure, and how do you avoid trading one for the other?Excluding too much collapses genuinely different data rows onto one key, so a stable green row and a stable red row interleave and look like one unstable test. The test is not volatility but relevance: if changing the value changes what the test asserts, it belongs in the key; if it only records where or when the run happened, it does not.
- A parallel runner records the shard index as a parameter. Why is that worse than a plain timestamp?It fails intermittently rather than always. A test keeps its series while it lands on the same worker and forks the moment the runner reschedules it, so the trend survives some builds and breaks on others - which reads as an unexplained gap rather than an obvious reset, and takes far longer to trace back to the parameter.
saying these in an interview costs you the question
- Treats a one-point trend as missing carried history only
- Says only the parameter's name matters, not its value
- Removes the parameter when a reader still needs the value
- Assigns a fresh historyId per run as the fix
- Excludes every parameter and merges unrelated data rows