skip to content

Why does adding `-r junit` to a Newman command silence the terminal, and where does the XML land?

level: seniorimportance: should knowfreq 44%

answer

  1. The option default is a value, not a floor
  2. Supplying a list replaces the terminal reporter
  3. No export path means a chosen directory
  4. A timestamp lands in the file name
  5. A fixed artifact path matches nothing

basics

~20 s

Newman's reporters option defaults to a list holding cli, and supplying a value replaces that default, so cli never loads. A reporter given no export path writes under a newman directory, its default name carrying a timestamp.

solid answer

~40 s

Two separate defaults bite at once. First, `-r/--reporters` has the default value `['cli']`, and the option's value is produced by splitting the string you supply — so `-r junit` **replaces** the default and the terminal reporter is simply not in the list. The fix is `-r cli,junit`. Second, a reporter that is given no export path falls back to its own default name (`newman-run-report.xml` for `junit`, `newman-run-report.json` for `json`), and Newman's export writer rewrites that path: it drops any directory on it, sets the directory to `newman`, and appends a timestamp plus a trailing digit. The file therefore appears at `newman/newman-run-report-<timestamp>0.xml`, which no fixed artifact path will match. The fix is `--reporter-junit-export ./reports/junit.xml`.

code

bash · 4 lines
bash
newman run ./collection.json \
  -r cli,junit \
  --reporter-junit-export ./reports/junit.xml
test -f ./reports/junit.xml || { echo "no report written"; exit 1; }

go deeper

for a junior

Remember to list cli alongside any other reporter, and to give a file-writing reporter an explicit export path. Those two habits prevent both surprises before you ever have to debug them.

for a middle

Explain the mechanics: the reporters option carries a default value that a supplied list replaces outright, and an export-less reporter falls back to a default name that the writer relocates and timestamps.

for a senior

Walk a failing pipeline back in order — did the reporter resolve, was it in the list, was a path given, is the artifact path literal — and know that reporting never influences the exit code, so green tells you nothing about artifacts.

for a principal

Own the convention: one pinned export path per reporter, cli always present for readable logs, and an explicit existence check on the artifact so that silent evidence loss cannot survive a release.

## Two independent surprises in one command "I added a reporter and lost my output, and the file isn't where I told CI to look" is one complaint with two unrelated causes. Neither is a bug; both are defaults doing exactly what they were written to do. ## Why the terminal went quiet The `-r, --reporters` option is declared with the default value `['cli']` and a coercion that splits the supplied string on commas. Two consequences: - The default is a *value*, not a floor. Supplying the option overwrites it wholesale. - The coercion builds a fresh list from your string alone; nothing merges the default back in. So `-r junit` yields the list `['junit']`. The `cli` reporter is never constructed, and since the terminal summary is produced entirely by that reporter, there is nothing to print. The run is unaffected — every request still goes out, every assertion still runs, the exit code is still derived from the failures — but the terminal shows only Newman's own warnings. The fix is to name `cli` explicitly whenever you add anything else: ```bash newman run ./collection.json -r cli,junit ``` Note also that no space may sit around the commas: the whole argument is one string that gets split, so `-r cli, junit` produces a second reporter name with a leading space that resolves to nothing. ## Where the file actually went Each file-writing reporter pushes an export request carrying three things: a `name`, a `default` file name, and the `path` the user asked for. For `junit` the default is `newman-run-report.xml`; for `json` it is `newman-run-report.json`. Newman's export writer then decides the destination: 1. **If a path was supplied**, it is resolved to an absolute path and used as given. Missing directories are created. 2. **If no path was supplied**, the default name is parsed, its root and directory are cleared, the directory is set to `newman`, and a timestamp derived from the current time — with every non-digit replaced by a hyphen — plus a trailing `0` is appended to the base name. 3. **If the supplied path turns out to be an existing directory**, the default name plus that same timestamp suffix is appended inside it. So an unexported JUnit report lands at roughly `newman/newman-run-report-<timestamp>0.xml`, in a directory Newman created, under a name that is different on every run. A pipeline configured to archive `newman-run-report.xml` from the workspace root finds nothing, and a pipeline archiving `newman/*.xml` accumulates a new file per run. ## The command, and what you actually get | Command fragment | Terminal output | File written | |---|---|---| | *(no `-r` at all)* | full `cli` summary | none | | `-r junit` | none | `newman/newman-run-report-<timestamp>0.xml` | | `-r cli,junit` | full `cli` summary | `newman/newman-run-report-<timestamp>0.xml` | | `-r cli,junit --reporter-junit-export ./reports/junit.xml` | full `cli` summary | `./reports/junit.xml` | The last row is the one to write down. It is deterministic, it is greppable by a fixed artifact path, and it keeps the human-readable output that makes a failed step diagnosable from the log alone. ## Diagnosing it in a real pipeline When a step reports success but publishes nothing, work through the chain in order: - **Did the reporter load?** A reporter Newman could not resolve prints `could not find "<name>" reporter` and the run continues regardless. A missing reporter never fails the build for you. - **Was the reporter in the list at all?** Check whether something later in the command overrode `-r`, and whether the list still contains `cli`. - **Was an export path given?** Without one, look under `newman/` in the working directory before concluding nothing was written. - **Is the artifact path a glob or a literal?** A literal name will never match a timestamped file. - **Did the export path point at a directory?** Then the file is inside it under the timestamped default name, not at the path you named. ## The wider lesson Report production and run success are decoupled in Newman by design. The exit code comes from the run's failures; nothing about reporting feeds it. That means a pipeline can be simultaneously green and producing no evidence — and it will stay that way silently until someone opens the artifacts. Pin every reporter's export path explicitly, keep `cli` in the list so the log is readable on its own, and add a step that asserts the report file exists rather than trusting the runner to have written it.

  • Why does `-r cli, junit` with a space behave differently from `-r cli,junit`?
    The argument is one string that Newman splits on commas, with no trimming. `cli, junit` becomes two names, the second beginning with a space, which resolves to no package and no built-in. Newman warns that it could not find that reporter and runs on with only `cli` active.
  • You point a reporter's export option at an existing directory. What is written?
    The reporter's default file name, with the timestamp suffix appended, inside that directory. Newman checks whether the resolved export path is a directory and, if it is, joins the timestamped default name onto it rather than trying to overwrite the directory. The result is a new file per run, not a stable path.
  • The pipeline step is green but no report was archived. Where do you look first?
    At whether the reporter loaded at all — a name Newman cannot resolve only warns — and then at whether an export path was given. Without one, the file is under a `newman` directory with a timestamp in its name, which no literal artifact path matches. Report production never affects the exit code.

saying these in an interview costs you the question

  • Expects the cli reporter to survive an explicit reporters list
  • Assumes the default report lands in the working directory
  • Configures a literal artifact path against a timestamped file
  • Treats a green run as proof a report was written
  • Puts spaces after the commas in the reporters list
  • Points an export option at a directory expecting a fixed name