skip to content

In Allure 2, `RetryPlugin` flags every attempt but the last as hidden. What does that flag actually remove from the generated report, and what survives of those earlier attempts?

level: seniorimportance: should knowfreq 36%

answer

  1. removed from view, not from disk
  2. two ways to ask for results
  3. the default accessor filters one flag
  4. each attempt keeps its own data file

basics

~20 s

Hidden removes an attempt from the default result set most plugins read, so trees and widgets stop counting it. The attempt is still serialised to its own test-case data file in the report, reachable from the survivor by uid.

solid answer

~50 s

The hidden flag is a **visibility** marker, not a deletion. A parsed launch offers plugins two accessors: a default one that returns only results where the flag is false, and an unfiltered one that returns everything. Which accessor a plugin calls decides what it counts, and most of them take the default — which is exactly why the trees and the summary widgets show one row per test and totals that do not double-count repeated work. What survives is substantial: the step that writes per-result data takes the **unfiltered** set, so every attempt, hidden or not, gets its own file under the report's test-case data named after its `uid`. The `retries` block on the survivor carries that `uid` alongside the attempt's status, status message and time, which is the link a reader follows to reach the earlier attempt's full record.

go deeper

for a junior

Know that a hidden attempt has not been deleted. The report still contains it; it is simply not one of the rows you land on when you open the tree.

for a middle

Explain that a parsed launch offers two accessors, one filtering hidden results and one returning everything, and that which one a plugin calls is what decides whether repeated attempts reach its numbers.

for a senior

Be ready to diagnose the mismatch this produces: a summary showing one total and a trend showing another for the same run, because one read the filtered set and the other read the unfiltered one on purpose.

for a principal

Own the contract this implies for anyone extending the report. The convenient accessor silently excludes attempts and the deliberate one includes them, so every plugin has to state which population its number describes.

## Two ways to ask for results, and only one of them filters When Allure 2 parses a results directory it produces a launch object, and that object exposes its results through **two** accessors. One returns the complete set, every result the parser produced. The other is a convenience built on top of it that streams the complete set and keeps only the results whose `hidden` flag is false. Its documentation says what it is for in one line: *returns not hidden test results*. Every plugin in the pipeline chooses between them, and the choice is the whole mechanism. `RetryPlugin` runs early, sets `hidden` on every attempt but the survivor, and by doing so silently changes what every later plugin that takes the filtered accessor will see. That is not a side effect; it is the point. The trees, the status charts and the summary counts are built on the filtered set, so a suite in which many tests were each executed twice still reports the number of tests it has, not the number of executions. ## What hidden does not do Hidden is not a delete, and it is not a status change. Specifically: - **The result object is untouched apart from two booleans.** Its status, its timings, its steps, its parameters and its message all remain exactly as parsed. A hidden failure is still a failure. - **The result is still written into the report.** The step that serialises results to the report's data takes the **unfiltered** accessor and writes one file per result under the test-case data directory, named from the result's own `uid`. Hidden attempts get files exactly like visible ones. - **The result is still reachable.** The `retries` block on the survivor carries each earlier attempt's `uid`, and the `uid` is precisely what the data file is named after. The block is a set of pointers with just enough summary — status, status message, time — to render a list without loading anything. - **Other plugins can still see it.** Any plugin that deliberately takes the unfiltered accessor gets the hidden attempts back in full. ## Why some numbers count attempts and others do not This is where the mechanism turns into a real diagnostic skill. Two numbers computed over the same run can legitimately disagree, and the reason is which accessor produced each. | what is being built | accessor | counts hidden attempts? | |---|---|---| | the trees and the status summary | filtered | no | | the per-result data files | unfiltered | yes | | the retry trend | unfiltered | yes, deliberately | The retry trend is the clearest illustration. Its whole job is to count how much repeated execution a build absorbed, which is impossible from survivors alone — on the filtered set every attempt is a survivor and the retry figure would be zero on every build forever. So it takes the unfiltered set on purpose and splits it on the `retry` flag the grouping step already set. When someone reports that "the summary counts one number of tests but the trend counts more runs than that", nothing is broken. One number is survivors and the other is attempts, and each is correct for what it is measuring. ## The practical reading A few consequences are worth carrying into an incident, in order of how often they come up: 1. **A green summary can sit on top of red attempts.** If the last attempt passed, the survivor is a pass and every filtered count treats it as one. The earlier failure has not been erased — it is in the retries block and in its own data file — but it is not in the totals. 2. **The evidence is still there when you need it.** Anyone who has been told "the failing attempt is gone from the report" is usually looking at a tree, which is built on the filtered set. The record exists; the route to it is the survivor's retries list. 3. **A plugin author is one method call away from a wrong number.** Taking the filtered accessor is the easy, default-feeling choice, and it silently excludes attempts. Any widget that means to describe work done rather than tests run has to reach for the unfiltered one and say so. 4. **Hiding is not archiving.** Nothing prunes hidden results from the report, so a run with heavy repetition writes a data file for every attempt it made. The report is complete; it is only the front page that is reconciled.

  • Which part of the pipeline deliberately reads the unfiltered set, and why does it have to?
    The retry trend does. Its job is to count attempts, and on the filtered set every result is a survivor, so its retry figure would be zero on every build. The step that writes per-result data files takes the unfiltered set too, which is why hidden attempts still exist in the report.
  • Why does an entry in the retries block carry a uid at all?
    The uid is the link back. Every result is serialised to a file named after its uid, hidden or not, so the survivor's page can offer the earlier attempt's own record without duplicating any of it inside the block. Drop the uid and the summary becomes a dead end.

It is the difference between taking a notice off the board and putting it through the shredder. Nobody reading the board will find it any more, but the sheet is still in the drawer for anyone who has its reference number.

saying these in an interview costs you the question

  • Says hidden attempts are discarded before the report is written
  • Assumes every plugin sees the same set of results
  • Thinks the retries block contains the full earlier results
  • Treats a disagreement between two report numbers as a bug