skip to content

For parameterized and repeated tests, how do per-invocation names relate to @DisplayName, and what controls them?

level: middleimportance: nice to knowfreq 34%

answer

  1. @DisplayName = container/group name only
  2. name pattern = per-invocation label
  3. Parameterized: {index}, {0}, {argumentsWithNames}
  4. Repeated: {currentRepetition}, {totalRepetitions}
  5. LONG_/SHORT_DISPLAY_NAME constants for @RepeatedTest

basics

~10 s

@DisplayName names the whole parameterized or repeated test. Each individual invocation gets its own name from the test's name pattern (the name attribute), not from @DisplayName.

solid answer

~50 s

@DisplayName on a @ParameterizedTest or @RepeatedTest sets the display name of the test container — the overall entry shown in the report. The names of the individual invocations come from a separate name pattern: @ParameterizedTest(name = "...") and @RepeatedTest(name = "..."), which support placeholders. For parameterized tests these include {index}, {argumentsWithNames}, and {0}, {1} for positional arguments; for repeated tests {currentRepetition} and {totalRepetitions}, plus the predefined patterns RepeatedTest.LONG_DISPLAY_NAME and SHORT_DISPLAY_NAME. So @DisplayName and the name pattern are complementary: one labels the group, the other labels each run. If you omit @DisplayName the container still falls back to the method's (possibly generated) name, while each invocation is always rendered from the pattern. This separation lets a report read like "converts currency [1] USD -> EUR", "converts currency [2] USD -> GBP", under a single, human-readable group title.

go deeper

for a junior

Knows @DisplayName names the overall test and that parameterized tests show multiple runs.

for a middle

Distinguishes the container @DisplayName from the per-invocation name pattern and uses placeholders like {index}/{0}.

for a senior

Designs readable parameterized/repeated reports combining @DisplayName with rich name patterns and argument names.

for a principal

Standardizes invocation-naming patterns across the suite for log/CI readability and ensures argument names survive via the -parameters compiler flag where relevant.

## Two different names are in play A `@ParameterizedTest` or `@RepeatedTest` is really a **container** that produces several **invocations** (one per argument set / repetition). There are therefore two naming concerns: 1. **The container name** — the single entry that groups the invocations. 2. **The per-invocation name** — the label of each individual run. `@DisplayName` controls **only the container name**. The per-invocation names come from a **name pattern** declared on the annotation itself. ## Parameterized tests ```java @DisplayName("converts currency") @ParameterizedTest(name = "[{index}] {0} -> {1}") @CsvSource({"USD, EUR", "USD, GBP"}) void converts(String from, String to) { /* ... */ } ``` Report: ``` converts currency <- from @DisplayName [1] USD -> EUR <- from the name pattern [2] USD -> GBP ``` Useful placeholders in the `name` pattern: - `{index}` — 1-based invocation index. - `{0}`, `{1}`, ... — the positional arguments. - `{arguments}` — all arguments, comma-separated. - `{argumentsWithNames}` — arguments prefixed with parameter names. - `{displayName}` — the method's display name. The default pattern is `"[{index}] {argumentsWithNames}"` (exposed as `ParameterizedTest.DEFAULT_DISPLAY_NAME`). ## Repeated tests ```java @DisplayName("retries on transient failure") @RepeatedTest(value = 3, name = "attempt {currentRepetition} of {totalRepetitions}") void retries() { /* ... */ } ``` Placeholders for repeated tests: - `{currentRepetition}` — current iteration number. - `{totalRepetitions}` — total count. - `{displayName}` — the method display name. Predefined constants: `RepeatedTest.LONG_DISPLAY_NAME` (default) and `RepeatedTest.SHORT_DISPLAY_NAME`. ## How they combine - If you provide `@DisplayName`, it titles the group; if not, the container uses the method's generated/standard name. - The `name` pattern always governs each invocation's label, independent of `@DisplayName`. - A `DisplayNameGenerator` (from the previous question) affects the *container/method* name, not the per-invocation pattern. So to make a parameterized report readable you typically set **both**: a `@DisplayName` for the group and a descriptive `name` pattern for the invocations. Key terms: a **placeholder** is a `{...}` token replaced at runtime; an **invocation** is one execution of a parameterized/repeated test with a specific input or repetition number.

  • Which attribute controls the name of each parameterized invocation?
    The name attribute on @ParameterizedTest, e.g. @ParameterizedTest(name = "[{index}] {0}").
  • How do you reference the first argument inside a parameterized name pattern?
    With the positional placeholder {0} (the second is {1}, and so on).

saying these in an interview costs you the question

  • Thinking @DisplayName renames each individual invocation
  • Using {0} placeholders in @DisplayName instead of in the name attribute
  • Assuming generators affect the per-invocation pattern
  • Forgetting the default parameterized pattern is [{index}] {argumentsWithNames}

context